1 /* mpitest.c - test the mpi functions
2 * Copyright (C) 1998 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
];
42 my_strusage( int level
)
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";
69 #ifdef HAVE_LC_MESSAGES
70 setlocale( LC_MESSAGES
, "" );
72 setlocale( LC_ALL
, "" );
74 bindtextdomain( PACKAGE
, GNUPG_LOCALEDIR
);
75 textdomain( PACKAGE
);
80 mpi_print( FILE *fp
, MPI a
, int mode
)
85 return fprintf(fp
, "[MPI_NULL]");
88 n1
= gcry_mpi_get_nbits(a
);
89 n
+= fprintf(fp
, "[%u bits]", n1
);
95 rc
= gcry_mpi_aprint( GCRYMPI_FMT_HEX
, (void **)&buffer
, NULL
, a
);
108 fputs("stack underflow\n",stderr
);
111 mpi_add( stack
[stackidx
-2], stack
[stackidx
-2], stack
[stackidx
-1] );
119 fputs("stack underflow\n", stderr
);
122 mpi_sub( stack
[stackidx
-2], stack
[stackidx
-2], stack
[stackidx
-1] );
130 fputs("stack underflow\n", stderr
);
133 mpi_add_ui( stack
[stackidx
-1], stack
[stackidx
-1], 1 );
140 fputs("stack underflow\n", stderr
);
143 /* mpi_sub_ui( stack[stackidx-1], stack[stackidx-1], 1 ); */
150 fputs("stack underflow\n", stderr
);
153 mpi_mul( stack
[stackidx
-2], stack
[stackidx
-2], stack
[stackidx
-1] );
161 fputs("stack underflow\n", stderr
);
164 mpi_mulm( stack
[stackidx
-3], stack
[stackidx
-3],
165 stack
[stackidx
-2], stack
[stackidx
-1] );
173 fputs("stack underflow\n", stderr
);
176 mpi_fdiv_q( stack
[stackidx
-2], stack
[stackidx
-2], stack
[stackidx
-1] );
184 fputs("stack underflow\n", stderr
);
187 mpi_fdiv_r( stack
[stackidx
-2], stack
[stackidx
-2], stack
[stackidx
-1] );
196 fputs("stack underflow\n", stderr
);
200 mpi_powm( a
, stack
[stackidx
-3], stack
[stackidx
-2], stack
[stackidx
-1] );
201 mpi_free(stack
[stackidx
-3]);
202 stack
[stackidx
-3] = a
;
209 MPI a
= mpi_alloc(40);
211 fputs("stack underflow\n", stderr
);
214 mpi_invm( a
, stack
[stackidx
-2], stack
[stackidx
-1] );
215 mpi_set(stack
[stackidx
-2],a
);
223 MPI a
= mpi_alloc(40);
225 fputs("stack underflow\n", stderr
);
228 mpi_gcd( a
, stack
[stackidx
-2], stack
[stackidx
-1] );
229 mpi_set(stack
[stackidx
-2],a
);
238 fputs("stack underflow\n", stderr
);
241 mpi_rshift( stack
[stackidx
-1],stack
[stackidx
-1], 1 );
246 main(int argc
, char **argv
)
248 static ARGPARSE_OPTS opts
[] = {
260 set_strusage( my_strusage
);
262 while( arg_parse( &pargs
, opts
) ) {
263 switch( pargs
.r_opt
) {
264 default : pargs
.err
= 2; break;
271 for(i
=0; i
< STACKSIZE
; i
++ )
275 while( (c
=getc(stdin
)) != EOF
) {
276 if( !state
) { /* waiting */
284 else if( isspace(c
) )
289 if( (c
=getc(stdin
)) == '+' )
297 if( (c
=getc(stdin
)) == '-' )
299 else if( isdigit(c
) || (c
>='A' && c
<= 'F') ) {
336 case 'i': /* dummy */
338 fputs("stack underflow\n", stderr
);
340 mpi_free(stack
[stackidx
-1]);
344 case 'd': /* duplicate the tos */
346 fputs("stack underflow\n", stderr
);
347 else if( stackidx
< STACKSIZE
) {
348 mpi_free(stack
[stackidx
]);
349 stack
[stackidx
] = mpi_copy( stack
[stackidx
-1] );
353 fputs("stack overflow\n", stderr
);
356 for(i
=0; i
< stackidx
; i
++ )
357 mpi_free(stack
[i
]), stack
[i
] = NULL
;
360 case 'p': /* print the tos */
362 puts("stack is empty");
364 mpi_print(stdout
, stack
[stackidx
-1], 1 );
368 case 'f': /* print the stack */
369 for( i
= stackidx
-1 ; i
>= 0; i
-- ) {
370 printf("[%2d]: ", i
);
371 mpi_print(stdout
, stack
[i
], 1 );
376 fputs("invalid operator\n", stderr
);
380 else if( state
== 1 ) { /* in a number */
381 if( !isxdigit(c
) ) { /* store the number */
387 if( stackidx
< STACKSIZE
) {
388 if( !stack
[stackidx
] )
389 stack
[stackidx
] = mpi_alloc(10);
390 if( mpi_fromstr(stack
[stackidx
], strbuf
) )
391 fputs("invalid number\n", stderr
);
396 fputs("stack overflow\n", stderr
);
398 else { /* store digit */
400 strbuf
[stridx
++] = c
;
401 else if( stridx
== 999 ) {
403 fputs("string too large - truncated\n", stderr
);
410 for(i
=0; i
< stackidx
; i
++ )