int main (int argc, char **argv) { const char *pgm; int last_argc = -1; int print_config = 0; int i, c; int state = 0; char strbuf[4096]; int stridx = 0; if (argc) { pgm = strrchr (*argv, '/'); if (pgm) pgm++; else pgm = *argv; argc--; argv++; } else pgm = "?"; while (argc && last_argc != argc ) { last_argc = argc; if (!strcmp (*argv, "--")) { argc--; argv++; break; } else if (!strcmp (*argv, "--version") || !strcmp (*argv, "--help")) { printf ("%s " MPICALC_VERSION "\n" "libgcrypt %s\n" "Copyright (C) 1997, 2013 Werner Koch\n" "License LGPLv2.1+: GNU LGPL version 2.1 or later " "<http://gnu.org/licenses/old-licenses/lgpl-2.1.html>\n" "This is free software: you are free to change and " "redistribute it.\n" "There is NO WARRANTY, to the extent permitted by law.\n" "\n" "Syntax: mpicalc [options]\n" "Simple interactive big integer RPN calculator\n" "\n" "Options:\n" " --version print version information\n" " --print-config print the Libgcrypt config\n" " --disable-hwf NAME disable feature NAME\n", pgm, gcry_check_version (NULL)); exit (0); } else if (!strcmp (*argv, "--print-config")) { argc--; argv++; print_config = 1; } else if (!strcmp (*argv, "--disable-hwf")) { argc--; argv++; if (argc) { if (gcry_control (GCRYCTL_DISABLE_HWF, *argv, NULL)) fprintf (stderr, "%s: unknown hardware feature `%s'" " - option ignored\n", pgm, *argv); argc--; argv++; } } } if (argc) { fprintf (stderr, "usage: %s [options] (--help for help)\n", pgm); exit (1); } if (!gcry_check_version (NEED_LIBGCRYPT_VERSION)) { fprintf (stderr, "%s: Libgcrypt is too old (need %s, have %s)\n", pgm, NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); exit (1); } gcry_control (GCRYCTL_DISABLE_SECMEM, 0); gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); if (print_config) { gcry_control (GCRYCTL_PRINT_CONFIG, stdout); exit (0); } for (i = 0; i < STACKSIZE; i++) stack[i] = NULL; stackidx = 0; while ((c = my_getc ()) != EOF) { if (!state) /* waiting */ { if (isdigit (c)) { state = 1; ungetc (c, stdin); strbuf[0] = '0'; strbuf[1] = 'x'; stridx = 2; } else if (isspace (c)) ; else { switch (c) { case '#': state = 2; break; case '+': if ((c = my_getc ()) == '+') do_inc (); else { ungetc (c, stdin); do_add (); } break; case '-': if ((c = my_getc ()) == '-') do_dec (); else if (isdigit (c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) { state = 1; ungetc (c, stdin); strbuf[0] = '-'; strbuf[1] = '0'; strbuf[2] = 'x'; stridx = 3; } else { ungetc (c, stdin); do_sub (); } break; case '*': do_mul (); break; case 'm': do_mulm (); break; case '/': do_div (); break; case '%': do_rem (); break; case '^': do_powm (); break; case '<': do_lshift (); break; case '>': do_rshift (); break; case 'I': do_inv (); break; case 'G': do_gcd (); break; case 'i': /* dummy */ if (!stackidx) fputs ("stack underflow\n", stderr); else { mpi_release (stack[stackidx - 1]); stackidx--; } break; case 'd': /* duplicate the tos */ if (!stackidx) fputs ("stack underflow\n", stderr); else if (stackidx < STACKSIZE) { mpi_release (stack[stackidx]); stack[stackidx] = mpi_copy (stack[stackidx - 1]); stackidx++; } else fputs ("stack overflow\n", stderr); break; case 'r': /* swap top elements */ if (stackidx < 2) fputs ("stack underflow\n", stderr); else if (stackidx < STACKSIZE) { gcry_mpi_t tmp = stack[stackidx-1]; stack[stackidx-1] = stack[stackidx - 2]; stack[stackidx-2] = tmp; } break; case 'b': do_nbits (); break; case 'P': do_primecheck (); break; case 'c': for (i = 0; i < stackidx; i++) { mpi_release (stack[i]); stack[i] = NULL; } stackidx = 0; break; case 'p': /* print the tos */ if (!stackidx) puts ("stack is empty"); else { print_mpi (stack[stackidx - 1]); putchar ('\n'); } break; case 'f': /* print the stack */ for (i = stackidx - 1; i >= 0; i--) { printf ("[%2d]: ", i); print_mpi (stack[i]); putchar ('\n'); } break; case '?': print_help (); break; default: fputs ("invalid operator\n", stderr); } } } else if (state == 1) /* In a number. */ { if (!isxdigit (c)) { /* Store the number */ state = 0; ungetc (c, stdin); if (stridx < sizeof strbuf) strbuf[stridx] = 0; if (stackidx < STACKSIZE) { if (!stack[stackidx]) stack[stackidx] = mpi_new (0); if (scan_mpi (stack[stackidx], strbuf)) fputs ("invalid number\n", stderr); else stackidx++; } else fputs ("stack overflow\n", stderr); } else { /* Store a digit. */ if (stridx < sizeof strbuf - 1) strbuf[stridx++] = c; else if (stridx == sizeof strbuf - 1) { strbuf[stridx] = 0; fputs ("input too large - truncated\n", stderr); stridx++; } } } else if (state == 2) /* In a comment. */ { if (c == '\n') state = 0; } } for (i = 0; i < stackidx; i++) mpi_release (stack[i]); return 0; }
RangeData operator ^ (const RangeData& other) { return RangeData(do_gcd(gcd, other.gcd)); }
int main(int argc, char **argv) { static ARGPARSE_OPTS opts[] = { {0} }; ARGPARSE_ARGS pargs; int i, c; int state = 0; char strbuf[1000]; int stridx=0; pargs.argc = &argc; pargs.argv = &argv; pargs.flags = 0; i18n_init(); while( arg_parse( &pargs, opts) ) { switch( pargs.r_opt ) { default : pargs.err = 2; break; } } if( argc ) usage(1); for(i=0; i < STACKSIZE; i++ ) stack[i] = NULL; stackidx =0; while( (c=getc(stdin)) != EOF ) { if( !state ) { /* waiting */ if( isdigit(c) ) { state = 1; ungetc(c, stdin); strbuf[0] = '0'; strbuf[1] = 'x'; stridx=2; } else if( isspace(c) ) ; else { switch(c) { case '+': if( (c=getc(stdin)) == '+' ) do_inc(); else { ungetc(c, stdin); do_add(); } break; case '-': if( (c=getc(stdin)) == '-' ) do_dec(); else if( isdigit(c) || (c >='A' && c <= 'F') ) { state = 1; ungetc(c, stdin); strbuf[0] = '-'; strbuf[1] = '0'; strbuf[2] = 'x'; stridx=3; } else { ungetc(c, stdin); do_sub(); } break; case '*': do_mul(); break; case 'm': do_mulm(); break; case '/': do_div(); break; case '%': do_rem(); break; case '^': do_powm(); break; case 'I': do_inv(); break; case 'G': do_gcd(); break; case '>': do_rshift(); break; case 'i': /* dummy */ if( !stackidx ) fputs("stack underflow\n", stderr); else { mpi_free(stack[stackidx-1]); stackidx--; } break; case 'd': /* duplicate the tos */ if( !stackidx ) fputs("stack underflow\n", stderr); else if( stackidx < STACKSIZE ) { mpi_free(stack[stackidx]); stack[stackidx] = mpi_copy( stack[stackidx-1] ); stackidx++; } else fputs("stack overflow\n", stderr); break; case 'c': for(i=0; i < stackidx; i++ ) mpi_free(stack[i]), stack[i] = NULL; stackidx = 0; break; case 'p': /* print the tos */ if( !stackidx ) puts("stack is empty"); else { mpi_print(stdout, stack[stackidx-1], 1 ); putchar('\n'); } break; case 'f': /* print the stack */ for( i = stackidx-1 ; i >= 0; i-- ) { printf("[%2d]: ", i ); mpi_print(stdout, stack[i], 1 ); putchar('\n'); } break; default: fputs("invalid operator\n", stderr); } } } else if( state == 1 ) { /* in a number */ if( !isxdigit(c) ) { /* store the number */ state = 0; ungetc(c, stdin); if( stridx < 1000 ) strbuf[stridx] = 0; if( stackidx < STACKSIZE ) { if( !stack[stackidx] ) stack[stackidx] = mpi_alloc(10); if( mpi_fromstr(stack[stackidx], strbuf) ) fputs("invalid number\n", stderr); else stackidx++; } else fputs("stack overflow\n", stderr); } else { /* store digit */ if( stridx < 999 ) strbuf[stridx++] = c; else if( stridx == 999 ) { strbuf[stridx] = 0; fputs("string too large - truncated\n", stderr); stridx++; } } } } for(i=0; i < stackidx; i++ ) mpi_free(stack[i]); return 0; }
int do_gcd(int a, int b) { return b ? do_gcd(b, a % b) : a; }