~ubuntu-branches/ubuntu/oneiric/gnupg2/oneiric-updates

« back to all changes in this revision

Viewing changes to tools/mpicalc.c

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Viehmann
  • Date: 2008-10-04 10:25:53 UTC
  • mfrom: (5.1.15 intrepid)
  • Revision ID: james.westby@ubuntu.com-20081004102553-fv62pp8dsitxli47
Tags: 2.0.9-3.1
* Non-maintainer upload.
* agent/gpg-agent.c: Deinit the threading library before exec'ing
  the command to run in --daemon mode. And because that still doesn't
  restore the sigprocmask, do that manually. Closes: #499569

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* mpitest.c - test the mpi functions
2
 
 *      Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3
 
 *
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
8
 
 *
9
 
 *
10
 
 * This file is part of GnuPG.
11
 
 *
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.
16
 
 *
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.
21
 
 *
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
25
 
 */
26
 
 
27
 
#include <config.h>
28
 
#include <stdio.h>
29
 
#include <stdlib.h>
30
 
#include <ctype.h>
31
 
 
32
 
#include "util.h"
33
 
#include "mpi.h"
34
 
#include "i18n.h"
35
 
 
36
 
#define STACKSIZE  100
37
 
static MPI stack[STACKSIZE];
38
 
static int stackidx;
39
 
 
40
 
 
41
 
const char *
42
 
strusage( int level )
43
 
{
44
 
    const char *p;
45
 
    switch( level ) {
46
 
      case 10:
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;
51
 
      case 1:
52
 
      case 11:  p = "Usage: mpicalc (-h for help)";
53
 
                break;
54
 
      case 2:
55
 
      case 12:  p =
56
 
    "\nSyntax: mpicalc [options] [files]\n"
57
 
    "MPI RPN calculator\n";
58
 
        break;
59
 
      default:  p = default_strusage(level);
60
 
    }
61
 
    return p;
62
 
}
63
 
 
64
 
 
65
 
static void
66
 
i18n_init(void)
67
 
{
68
 
  #ifdef ENABLE_NLS
69
 
    #ifdef HAVE_LC_MESSAGES
70
 
       setlocale( LC_MESSAGES, "" );
71
 
    #else
72
 
       setlocale( LC_ALL, "" );
73
 
    #endif
74
 
    bindtextdomain( PACKAGE, G10_LOCALEDIR );
75
 
    textdomain( PACKAGE );
76
 
  #endif
77
 
}
78
 
 
79
 
 
80
 
static void
81
 
do_add(void)
82
 
{
83
 
    if( stackidx < 2 ) {
84
 
        fputs("stack underflow\n",stderr);
85
 
        return;
86
 
    }
87
 
    mpi_add( stack[stackidx-2], stack[stackidx-2], stack[stackidx-1] );
88
 
    stackidx--;
89
 
}
90
 
 
91
 
static void
92
 
do_sub(void)
93
 
{
94
 
    if( stackidx < 2 ) {
95
 
        fputs("stack underflow\n", stderr);
96
 
        return;
97
 
    }
98
 
    mpi_sub( stack[stackidx-2], stack[stackidx-2], stack[stackidx-1] );
99
 
    stackidx--;
100
 
}
101
 
 
102
 
static void
103
 
do_inc(void)
104
 
{
105
 
    if( stackidx < 1 ) {
106
 
        fputs("stack underflow\n", stderr);
107
 
        return;
108
 
    }
109
 
    mpi_add_ui( stack[stackidx-1], stack[stackidx-1], 1 );
110
 
}
111
 
 
112
 
static void
113
 
do_dec(void)
114
 
{
115
 
    if( stackidx < 1 ) {
116
 
        fputs("stack underflow\n", stderr);
117
 
        return;
118
 
    }
119
 
 /* mpi_sub_ui( stack[stackidx-1], stack[stackidx-1], 1 ); */
120
 
}
121
 
 
122
 
static void
123
 
do_mul(void)
124
 
{
125
 
    if( stackidx < 2 ) {
126
 
        fputs("stack underflow\n", stderr);
127
 
        return;
128
 
    }
129
 
    mpi_mul( stack[stackidx-2], stack[stackidx-2], stack[stackidx-1] );
130
 
    stackidx--;
131
 
}
132
 
 
133
 
static void
134
 
do_mulm(void)
135
 
{
136
 
    if( stackidx < 3 ) {
137
 
        fputs("stack underflow\n", stderr);
138
 
        return;
139
 
    }
140
 
    mpi_mulm( stack[stackidx-3], stack[stackidx-3],
141
 
                                 stack[stackidx-2], stack[stackidx-1] );
142
 
    stackidx -= 2;
143
 
}
144
 
 
145
 
static void
146
 
do_div(void)
147
 
{
148
 
    if( stackidx < 2 ) {
149
 
        fputs("stack underflow\n", stderr);
150
 
        return;
151
 
    }
152
 
    mpi_fdiv_q( stack[stackidx-2], stack[stackidx-2], stack[stackidx-1] );
153
 
    stackidx--;
154
 
}
155
 
 
156
 
static void
157
 
do_rem(void)
158
 
{
159
 
    if( stackidx < 2 ) {
160
 
        fputs("stack underflow\n", stderr);
161
 
        return;
162
 
    }
163
 
    mpi_fdiv_r( stack[stackidx-2], stack[stackidx-2], stack[stackidx-1] );
164
 
    stackidx--;
165
 
}
166
 
 
167
 
static void
168
 
do_powm(void)
169
 
{
170
 
    MPI a;
171
 
    if( stackidx < 3 ) {
172
 
        fputs("stack underflow\n", stderr);
173
 
        return;
174
 
    }
175
 
    a= mpi_alloc(10);
176
 
    mpi_powm( a, stack[stackidx-3], stack[stackidx-2], stack[stackidx-1] );
177
 
    mpi_free(stack[stackidx-3]);
178
 
    stack[stackidx-3] = a;
179
 
    stackidx -= 2;
180
 
}
181
 
 
182
 
static void
183
 
do_inv(void)
184
 
{
185
 
    MPI a = mpi_alloc(40);
186
 
    if( stackidx < 2 ) {
187
 
        fputs("stack underflow\n", stderr);
188
 
        return;
189
 
    }
190
 
    mpi_invm( a, stack[stackidx-2], stack[stackidx-1] );
191
 
    mpi_set(stack[stackidx-2],a);
192
 
    mpi_free(a);
193
 
    stackidx--;
194
 
}
195
 
 
196
 
static void
197
 
do_gcd(void)
198
 
{
199
 
    MPI a = mpi_alloc(40);
200
 
    if( stackidx < 2 ) {
201
 
        fputs("stack underflow\n", stderr);
202
 
        return;
203
 
    }
204
 
    mpi_gcd( a, stack[stackidx-2], stack[stackidx-1] );
205
 
    mpi_set(stack[stackidx-2],a);
206
 
    mpi_free(a);
207
 
    stackidx--;
208
 
}
209
 
 
210
 
static void
211
 
do_rshift(void)
212
 
{
213
 
    if( stackidx < 1 ) {
214
 
        fputs("stack underflow\n", stderr);
215
 
        return;
216
 
    }
217
 
    mpi_rshift( stack[stackidx-1],stack[stackidx-1], 1 );
218
 
}
219
 
 
220
 
 
221
 
int
222
 
main(int argc, char **argv)
223
 
{
224
 
    static ARGPARSE_OPTS opts[] = {
225
 
    {0} };
226
 
    ARGPARSE_ARGS pargs;
227
 
    int i, c;
228
 
    int state = 0;
229
 
    char strbuf[1000];
230
 
    int stridx=0;
231
 
 
232
 
    pargs.argc = &argc;
233
 
    pargs.argv = &argv;
234
 
    pargs.flags = 0;
235
 
 
236
 
    i18n_init();
237
 
    while( arg_parse( &pargs, opts) ) {
238
 
        switch( pargs.r_opt ) {
239
 
          default : pargs.err = 2; break;
240
 
        }
241
 
    }
242
 
    if( argc )
243
 
        usage(1);
244
 
 
245
 
 
246
 
    for(i=0; i < STACKSIZE; i++ )
247
 
        stack[i] = NULL;
248
 
    stackidx =0;
249
 
 
250
 
    while( (c=getc(stdin)) != EOF ) {
251
 
        if( !state ) {  /* waiting */
252
 
            if( isdigit(c) ) {
253
 
                state = 1;
254
 
                ungetc(c, stdin);
255
 
                strbuf[0] = '0';
256
 
                strbuf[1] = 'x';
257
 
                stridx=2;
258
 
            }
259
 
            else if( isspace(c) )
260
 
                ;
261
 
            else {
262
 
                switch(c) {
263
 
                  case '+':
264
 
                    if( (c=getc(stdin)) == '+' )
265
 
                        do_inc();
266
 
                    else {
267
 
                        ungetc(c, stdin);
268
 
                        do_add();
269
 
                    }
270
 
                    break;
271
 
                  case '-':
272
 
                    if( (c=getc(stdin)) == '-' )
273
 
                        do_dec();
274
 
                    else if( isdigit(c) || (c >='A' && c <= 'F') ) {
275
 
                        state = 1;
276
 
                        ungetc(c, stdin);
277
 
                        strbuf[0] = '-';
278
 
                        strbuf[1] = '0';
279
 
                        strbuf[2] = 'x';
280
 
                        stridx=3;
281
 
                    }
282
 
                    else {
283
 
                        ungetc(c, stdin);
284
 
                        do_sub();
285
 
                    }
286
 
                    break;
287
 
                  case '*':
288
 
                    do_mul();
289
 
                    break;
290
 
                  case 'm':
291
 
                    do_mulm();
292
 
                    break;
293
 
                  case '/':
294
 
                    do_div();
295
 
                    break;
296
 
                  case '%':
297
 
                    do_rem();
298
 
                    break;
299
 
                  case '^':
300
 
                    do_powm();
301
 
                    break;
302
 
                  case 'I':
303
 
                    do_inv();
304
 
                    break;
305
 
                  case 'G':
306
 
                    do_gcd();
307
 
                    break;
308
 
                  case '>':
309
 
                    do_rshift();
310
 
                    break;
311
 
                  case 'i': /* dummy */
312
 
                    if( !stackidx )
313
 
                        fputs("stack underflow\n", stderr);
314
 
                    else {
315
 
                        mpi_free(stack[stackidx-1]);
316
 
                        stackidx--;
317
 
                    }
318
 
                    break;
319
 
                  case 'd': /* duplicate the tos */
320
 
                    if( !stackidx )
321
 
                        fputs("stack underflow\n", stderr);
322
 
                    else if( stackidx < STACKSIZE ) {
323
 
                        mpi_free(stack[stackidx]);
324
 
                        stack[stackidx] = mpi_copy( stack[stackidx-1] );
325
 
                        stackidx++;
326
 
                    }
327
 
                    else
328
 
                        fputs("stack overflow\n", stderr);
329
 
                    break;
330
 
                  case 'c':
331
 
                    for(i=0; i < stackidx; i++ )
332
 
                        mpi_free(stack[i]), stack[i] = NULL;
333
 
                    stackidx = 0;
334
 
                    break;
335
 
                  case 'p': /* print the tos */
336
 
                    if( !stackidx )
337
 
                        puts("stack is empty");
338
 
                    else {
339
 
                        mpi_print(stdout, stack[stackidx-1], 1 );
340
 
                        putchar('\n');
341
 
                    }
342
 
                    break;
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 );
347
 
                        putchar('\n');
348
 
                    }
349
 
                    break;
350
 
                  default:
351
 
                    fputs("invalid operator\n", stderr);
352
 
                }
353
 
            }
354
 
        }
355
 
        else if( state == 1 ) { /* in a number */
356
 
            if( !isxdigit(c) ) { /* store the number */
357
 
                state = 0;
358
 
                ungetc(c, stdin);
359
 
                if( stridx < 1000 )
360
 
                    strbuf[stridx] = 0;
361
 
 
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);
367
 
                    else
368
 
                        stackidx++;
369
 
                }
370
 
                else
371
 
                    fputs("stack overflow\n", stderr);
372
 
            }
373
 
            else { /* store digit */
374
 
                if( stridx < 999 )
375
 
                    strbuf[stridx++] = c;
376
 
                else if( stridx == 999 ) {
377
 
                    strbuf[stridx] = 0;
378
 
                    fputs("string too large - truncated\n", stderr);
379
 
                    stridx++;
380
 
                }
381
 
            }
382
 
        }
383
 
 
384
 
    }
385
 
    for(i=0; i < stackidx; i++ )
386
 
        mpi_free(stack[i]);
387
 
    return 0;
388
 
}
389
 
 
390