Пример #1
0
ostream &
SMKStrStreambuf::dumpInfo(
  ostream &	dest,
  const char *  prefix,
  bool		showVer
  )
{
  if( showVer )
    dest << SMKStrStreambuf::getClassName() << ":\n"
	 << SMKStrStreambuf::getVersion() << '\n';

  dest << prefix << "length:  " << plen() << '\n'
#if defined( SMK_HAVE_STRBUF_BASE )
       << prefix << "base():  " << (void *) base() << '\n'
#endif
#if defined( SMK_HAVE_STRBUF_EBUF )
       << prefix << "ebuf():  " << (void *) ebuf() << '\n'
#endif
       << prefix << "pbase(): " << (void *) pbase() << '\n'
       << prefix << "pptr():  " << (void *) pptr() << '\n'
       << prefix << "epptr(): " << (void *) epptr() << '\n'
       << prefix << "eback(): " << (void *) eback() << '\n'
       << prefix << "gptr():  " << (void *) gptr() << '\n'
       << prefix << "egptr(): " << (void *) egptr() << '\n'
       << prefix << "n - b:   " << pptr() - pbase() << '\n'
       << prefix << "string:  '" << (void *)cstr() << "'\n"
       << prefix << "pbase(): " << (void *) pbase() << '\n'
       << prefix << "pptr():  " << (void *) pptr() << '\n'
       << prefix << "length:  " << plen() << '\n'
       << prefix << "size:    " << psize() << '\n'
    ;

  return( dest );
}
char * concat(char *a, char* b){
	char* c;
	int la,lb;
	printf("Inizio funzione\n");
	la=len(a);
	lb=len(b);
	plen(la,"prima");
	plen(lb,"seconda");
	c=malloc(sizeof(char)*(la+lb+1));
	copy(a,c);
	copy(b,c+la);
	printf("Fine funzione\n");
	return c;
	}
Пример #3
0
// (term-prinl ['num 'num] 'any ..) -> any
any plisp_term_prinl(any ex) {
  any x, y;
  long n1, n2;

  // if number of args > 1, we accept
  // a min of 3 args - x, y and the value
  // to print.
  if (plen(ex) > 1 && isNum(cadr(ex)) && isNum(caddr(ex))) {
    x = cdr(ex), y = EVAL(car(x));
    NeedNum(ex, y);
    n1 = unBox(y); // we get x here.
    x = cdr(x), y = EVAL(car(x));
    NeedNum(ex, y);
    n2 = unBox(y); // we get y here.
    term_gotoxy(n1, n2);
    // now, get the rest of the params
    // and prinl.
    while (isCell(x = cdr(x)))
      ptermh_prin(y = EVAL(car(x)));
  } else {
    // We don't have the coordinates.
    // we just print the first value
    // in the list (including NIL).
    x = cdr(ex), y = EVAL(car(x));
    ptermh_prin(y);
    while (isCell(x = cdr(x)))
      ptermh_prin(y = EVAL(car(x)));
  }

  newline();
  return y;
}
Пример #4
0
static poly_t
rdpoly(const char *name, int flags, int bperhx) {
	/* read poly from file in chunks and report errors */

	poly_t apoly = PZERO, chunk = PZERO;
	FILE *input;

	input = oread(name);
	while(!feof(input) && !ferror(input)) {
		chunk = filtop(input, BUFFER, flags, bperhx);
		psum(&apoly, chunk, plen(apoly));
		pfree(&chunk);
	}
	if(ferror(input)) {
		fprintf(stderr,"%s: error condition on file '%s'\n", myname, name);
		exit(EXIT_FAILURE);
	}
	/* close file unless stdin */
	if(input == stdin)
		/* reset EOF condition */
		clearerr(input);
	else if(fclose(input)) {
		fprintf(stderr,"%s: error closing file '%s'\n", myname, name);
		exit(EXIT_FAILURE);
	}
	return(apoly);
}
Пример #5
0
// (tmr-delay ['num] 'num) -> Nil
any tmr_delay(any ex) {
  timer_data_type period;
  unsigned id = PLATFORM_TIMER_SYS_ID;
  any x, y;

  x = cdr(ex), y = EVAL(car(x));
  if (plen(ex) == 1) {
    // We only have 1 parameter. Assume
    // *tmr-sys-timer* and get the time
    // period.
    NeedNum(ex, y);
    period = (timer_data_type)unBox(y);
  } else {
    // Minimum 2 args required here - the
    // id and the period. Ignore the others.
    NeedNum(ex, y);
    id = unBox(y);
    MOD_CHECK_TIMER(ex, id);
    x = cdr(x), y = EVAL(car(x));
    NeedNum(ex, y);
    period = unBox(y);
  }
  platform_timer_delay(id, period);
  return Nil;
}
Пример #6
0
//两圆相交的面积
double Circle2S(double x1,double y1,double r1,double x2,double y2,double r2)
{
    double dis = plen(x1,y1,x2,y2);
    double R = max(r1,r2);
    double r = min(r1,r2);
    if(dblcmp(dis - (R + r)) >= 0) return 0;
    if(dblcmp(dis - (R - r)) <= 0) return PI*r*r;
    double Se1 = Sector_S(triA(r2,r1,dis),r1)*2;
    double Se2 = Sector_S(triA(r1,r2,dis),r2)*2;
    double triS = Heron(r1,r2,dis)*2;
    return Se1 + Se2 - triS;
}
Пример #7
0
static void simple_send(char *buf, int len) {
    if( term_buflen != 0 )
    {
	back->send(term_buf, term_buflen);
	while (term_buflen > 0) {
	    bsb(plen(term_buf[term_buflen-1]));
	    term_buflen--;
	}
    }
    if (len > 0)
        back->send(buf, len);
}
Пример #8
0
// (tmr-getclock ['num]) -> num
any tmr_getclock(any ex) {
  timer_data_type res;
  unsigned id = PLATFORM_TIMER_SYS_ID;
  any x, y;

  x = cdr(ex), y = EVAL(car(x));
  if (plen(ex) > 0) {
    NeedNum(ex, y);
    id = unBox(y);
    MOD_CHECK_TIMER(ex, id);
  }
  res = platform_timer_op(id, PLATFORM_TIMER_OP_GET_CLOCK, 0);
  return box(res);
}
Пример #9
0
// (tmr-start ['num]) -> num
any tmr_start(any ex) {
  unsigned id = PLATFORM_TIMER_SYS_ID;
  timer_data_type res;
  any x, y;

  x = cdr(ex), y = EVAL(car(x));
  if (plen(ex) > 0) {
    NeedNum(ex, y);
    id = unBox(y);
    MOD_CHECK_TIMER(ex, id);
  }

  res = platform_timer_op(id, PLATFORM_TIMER_OP_START, 0);
  return box(res);
}
Пример #10
0
// (term-getchar ['sym]) -> num
any plisp_term_getchar(any ex) {
  any x, y;
  int temp = TERM_INPUT_WAIT, ret;

  // if number of args is > 0
  // get value; else getchar()
  // will wait.
  if (plen(ex) > 0) {
    x = cdr(ex);
    NeedNum(ex, y = EVAL(car(x)));
    return ((ret = term_getch(temp = unBox(y))) == -1?
	    Nil : box(ret));
  }
  return ((ret = term_getch(temp)) == -1?
	  Nil : box(ret));
}
Пример #11
0
void
uprog(const poly_t gpoly, int flags, unsigned long seq) {
	/* Callback function to report search progress */
	char *string;

	/* Suppress first report in CLI */
	if(!seq)
		return;
	string = ptostr(gpoly, P_RTJUST, 4);
	fprintf(stderr, "%s: searching: width=%ld  poly=0x%s  refin=%s  refout=%s\n",
			myname, plen(gpoly), string,
			(flags & P_REFIN ? "true" : "false"),
			(flags & P_REFOUT ? "true" : "false")
			);
	free(string);
}
Пример #12
0
// (adc-getsamples 'num ['num]) -> lst
any plisp_adc_getsamples(any ex) {
#ifdef BUF_ENABLE_ADC
  unsigned id, i;
  u16 bcnt, count = 0;
  any x, y;
  cell c1;

  x = cdr(ex);
  NeedNum(ex, y = EVAL(car(x)));
  id = unBox(y); // get id
  MOD_CHECK_ID(ex, adc, id);

  if (plen(ex) >= 2) {
    x = cdr(x);
    NeedNum(ex, y = EVAL(car(x)));
    count = (u16)unBox(y); // get count
  }

  bcnt = adc_wait_samples(id, count);

  // If count is zero, grab all samples
  if (count == 0)
    count = bcnt;

  // Don't pull more samples than are available
  if (count > bcnt)
    count = bcnt;

  // Make the list of adc samples
  Push(c1, y = cons(box(adc_get_processed_sample(id)), Nil));
  for (i = 1; i < count - 1; i++)
    Push(c1, y = cons(box(adc_get_processed_sample(id)), y));

  return Pop(c1);
#else
  err(NULL, NULL, "BUF_ENABLE_ADC not defined");
#endif
}
Пример #13
0
void ldisc_send(Ldisc *ldisc, const void *vbuf, int len, bool interactive)
{
    const char *buf = (const char *)vbuf;
    int keyflag = 0;

    assert(ldisc->term);
    assert(len);

    if (interactive) {
        /*
         * Interrupt a paste from the clipboard, if one was in
         * progress when the user pressed a key. This is easier than
         * buffering the current piece of data and saving it until the
         * terminal has finished pasting, and has the potential side
         * benefit of permitting a user to cancel an accidental huge
         * paste.
         */
        term_nopaste(ldisc->term);
    }

    /*
     * Less than zero means null terminated special string.
     */
    if (len < 0) {
	len = strlen(buf);
	keyflag = KCTRL('@');
    }
    /*
     * Either perform local editing, or just send characters.
     */
    if (EDITING) {
	while (len--) {
	    int c;
	    c = (unsigned char)(*buf++) + keyflag;
	    if (!interactive && c == '\r')
		c += KCTRL('@');
	    switch (ldisc->quotenext ? ' ' : c) {
		/*
		 * ^h/^?: delete, and output BSBs, to return to
		 * last character boundary (in UTF-8 mode this may
		 * be more than one byte)
		 * ^w: delete, and output BSBs, to return to last
		 * space/nonspace boundary
		 * ^u: delete, and output BSBs, to return to BOL
		 * ^c: Do a ^u then send a telnet IP
		 * ^z: Do a ^u then send a telnet SUSP
		 * ^\: Do a ^u then send a telnet ABORT
		 * ^r: echo "^R\n" and redraw line
		 * ^v: quote next char
		 * ^d: if at BOL, end of file and close connection,
		 * else send line and reset to BOL
		 * ^m: send line-plus-\r\n and reset to BOL
		 */
	      case KCTRL('H'):
	      case KCTRL('?'):	       /* backspace/delete */
		if (ldisc->buflen > 0) {
		    do {
			if (ECHOING)
			    bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1]));
			ldisc->buflen--;
		    } while (!char_start(ldisc, ldisc->buf[ldisc->buflen]));
		}
		break;
	      case CTRL('W'):	       /* delete word */
		while (ldisc->buflen > 0) {
		    if (ECHOING)
			bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1]));
		    ldisc->buflen--;
		    if (ldisc->buflen > 0 &&
			isspace((unsigned char)ldisc->buf[ldisc->buflen-1]) &&
			!isspace((unsigned char)ldisc->buf[ldisc->buflen]))
			break;
		}
		break;
	      case CTRL('U'):	       /* delete line */
	      case CTRL('C'):	       /* Send IP */
	      case CTRL('\\'):	       /* Quit */
	      case CTRL('Z'):	       /* Suspend */
		while (ldisc->buflen > 0) {
		    if (ECHOING)
			bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1]));
		    ldisc->buflen--;
		}
                backend_special(ldisc->backend, SS_EL, 0);
                /*
                 * We don't send IP, SUSP or ABORT if the user has
                 * configured telnet specials off! This breaks
                 * talkers otherwise.
                 */
                if (!ldisc->telnet_keyboard)
                    goto default_case;
		if (c == CTRL('C'))
                    backend_special(ldisc->backend, SS_IP, 0);
		if (c == CTRL('Z'))
                    backend_special(ldisc->backend, SS_SUSP, 0);
		if (c == CTRL('\\'))
                    backend_special(ldisc->backend, SS_ABORT, 0);
		break;
	      case CTRL('R'):	       /* redraw line */
		if (ECHOING) {
		    int i;
		    c_write(ldisc, "^R\r\n", 4);
		    for (i = 0; i < ldisc->buflen; i++)
			pwrite(ldisc, ldisc->buf[i]);
		}
		break;
	      case CTRL('V'):	       /* quote next char */
		ldisc->quotenext = true;
		break;
	      case CTRL('D'):	       /* logout or send */
		if (ldisc->buflen == 0) {
                    backend_special(ldisc->backend, SS_EOF, 0);
		} else {
                    backend_send(ldisc->backend, ldisc->buf, ldisc->buflen);
		    ldisc->buflen = 0;
		}
		break;
		/*
		 * This particularly hideous bit of code from RDB
		 * allows ordinary ^M^J to do the same thing as
		 * magic-^M when in Raw protocol. The line `case
		 * KCTRL('M'):' is _inside_ the if block. Thus:
		 * 
		 *  - receiving regular ^M goes straight to the
		 *    default clause and inserts as a literal ^M.
		 *  - receiving regular ^J _not_ directly after a
		 *    literal ^M (or not in Raw protocol) fails the
		 *    if condition, leaps to the bottom of the if,
		 *    and falls through into the default clause
		 *    again.
		 *  - receiving regular ^J just after a literal ^M
		 *    in Raw protocol passes the if condition,
		 *    deletes the literal ^M, and falls through
		 *    into the magic-^M code
		 *  - receiving a magic-^M empties the line buffer,
		 *    signals end-of-line in one of the various
		 *    entertaining ways, and _doesn't_ fall out of
		 *    the bottom of the if and through to the
		 *    default clause because of the break.
		 */
	      case CTRL('J'):
		if (ldisc->protocol == PROT_RAW &&
		    ldisc->buflen > 0 && ldisc->buf[ldisc->buflen - 1] == '\r') {
		    if (ECHOING)
			bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1]));
		    ldisc->buflen--;
		    /* FALLTHROUGH */
	      case KCTRL('M'):	       /* send with newline */
		    if (ldisc->buflen > 0)
                        backend_send(ldisc->backend,
                                     ldisc->buf, ldisc->buflen);
		    if (ldisc->protocol == PROT_RAW)
                        backend_send(ldisc->backend, "\r\n", 2);
		    else if (ldisc->protocol == PROT_TELNET && ldisc->telnet_newline)
                        backend_special(ldisc->backend, SS_EOL, 0);
		    else
                        backend_send(ldisc->backend, "\r", 1);
		    if (ECHOING)
			c_write(ldisc, "\r\n", 2);
		    ldisc->buflen = 0;
		    break;
		}
		/* FALLTHROUGH */
	      default:		       /* get to this label from ^V handler */
                default_case:
                sgrowarray(ldisc->buf, ldisc->bufsiz, ldisc->buflen);
		ldisc->buf[ldisc->buflen++] = c;
		if (ECHOING)
		    pwrite(ldisc, (unsigned char) c);
		ldisc->quotenext = false;
		break;
	    }
	}
    } else {
	if (ldisc->buflen != 0) {
            backend_send(ldisc->backend, ldisc->buf, ldisc->buflen);
	    while (ldisc->buflen > 0) {
		bsb(ldisc, plen(ldisc, ldisc->buf[ldisc->buflen - 1]));
		ldisc->buflen--;
	    }
	}
	if (len > 0) {
	    if (ECHOING)
		c_write(ldisc, buf, len);
	    if (keyflag && ldisc->protocol == PROT_TELNET && len == 1) {
		switch (buf[0]) {
		  case CTRL('M'):
		    if (ldisc->protocol == PROT_TELNET && ldisc->telnet_newline)
                        backend_special(ldisc->backend, SS_EOL, 0);
		    else
                        backend_send(ldisc->backend, "\r", 1);
		    break;
		  case CTRL('?'):
		  case CTRL('H'):
		    if (ldisc->telnet_keyboard) {
                        backend_special(ldisc->backend, SS_EC, 0);
			break;
		    }
		  case CTRL('C'):
		    if (ldisc->telnet_keyboard) {
                        backend_special(ldisc->backend, SS_IP, 0);
			break;
		    }
		  case CTRL('Z'):
		    if (ldisc->telnet_keyboard) {
                        backend_special(ldisc->backend, SS_SUSP, 0);
			break;
		    }

		  default:
                    backend_send(ldisc->backend, buf, len);
		    break;
		}
	    } else
                backend_send(ldisc->backend, buf, len);
	}
    }
}
Пример #14
0
inline std::streamsize basic_dbgstreambuf<elem_t, traits_t>::xsputn(
    const elem_t* str,
    std::streamsize n)
{
    if (n <= plen())
    {
#if _MSC_VER >= 1400
        const size_t size_in_bytes = plen() * sizeof(elem_t);
        traits_t::_Copy_s(pptr(), size_in_bytes, str, n);
#else
        traits_t::copy(pptr(), str, n);
#endif

        const int off = static_cast<int>(n);
        pbump(off);

        return n;
    }

    const std::streamsize pos = ppos();
    const std::streamsize newlen = pos + n;

    if (elem_t* const newbuf = new (std::nothrow) elem_t[newlen + 1])
    {
#if _MSC_VER >= 1400
        size_t size_in_bytes = newlen * sizeof(elem_t);
        traits_t::_Copy_s(newbuf, size_in_bytes, pbase(), pos);
#else
        traits_t::copy(newbuf, pbase(), pos);
#endif

        setp(newbuf, newbuf + pos, newbuf + newlen);

        delete[] m_buf;
        m_buf = newbuf;

#if _MSC_VER >= 1400
        size_in_bytes = plen() * sizeof(elem_t);
        traits_t::_Copy_s(pptr(), size_in_bytes, str, n);
#else
        traits_t::copy(pptr(), str, n);
#endif

        const int off = static_cast<int>(n);
        pbump(off);

        return n;
    }

    const ptrdiff_t oldlen_ = epptr() - pbase();

    if (oldlen_ == 0)
    {
        elem_t buf[2];

        buf[1] = elem_t();

        for (std::streamsize i = 0; i < n; ++i)
        {
            buf[0] = *str++;
            OutputDebugStringX(buf);
        }

        return n;
    }

    std::streamsize nn = n;

    if (std::streamsize len = plen())
    {
#if _MSC_VER >= 1400
        const size_t size_in_bytes = len * sizeof(elem_t);
        traits_t::_Copy_s(pptr(), size_in_bytes, str, len);
#else
        traits_t::copy(pptr(), str, len);
#endif

        const int off = static_cast<int>(len);
        pbump(off);

        str += len;
        nn -= len;
    }

    const std::streamsize oldlen = static_cast<std::streamsize>(oldlen_);

#if _MSC_VER >= 1400
    const size_t size_in_bytes = oldlen * sizeof(elem_t);
#endif

    for (;;)
    {
        sync();

        if (nn <= oldlen)
        {
#if _MSC_VER >= 1400
            traits_t::_Copy_s(pbase(), size_in_bytes, str, nn);
#else
            traits_t::copy(pbase(), str, nn);
#endif

            const int off = static_cast<int>(nn);
            pbump(off);

            return n;
        }

#if _MSC_VER >= 1400
        traits_t::_Copy_s(pbase(), size_in_bytes, str, oldlen);
#else
        traits_t::copy(pbase(), str, oldlen);
#endif

        const int off = static_cast<int>(oldlen);
        pbump(off);

        str += oldlen;
        nn -= oldlen;
    }
}
Пример #15
0
static void term_send(char *buf, int len) {
    while (len--) {
	char c;
        c = *buf++;
	switch (term_quotenext ? ' ' : c) {
	    /*
	     * ^h/^?: delete one char and output one BSB
	     * ^w: delete, and output BSBs, to return to last space/nonspace
	     * boundary
	     * ^u: delete, and output BSBs, to return to BOL
	     * ^c: Do a ^u then send a telnet IP
	     * ^z: Do a ^u then send a telnet SUSP
	     * ^\: Do a ^u then send a telnet ABORT
	     * ^r: echo "^R\n" and redraw line
	     * ^v: quote next char
	     * ^d: if at BOL, end of file and close connection, else send line
	     * and reset to BOL
	     * ^m: send line-plus-\r\n and reset to BOL
	     */
	  case CTRL('H'): case CTRL('?'):      /* backspace/delete */
	    if (term_buflen > 0) {
		bsb(plen(term_buf[term_buflen-1]));
		term_buflen--;
	    }
	    break;
	  case CTRL('W'):		       /* delete word */
	    while (term_buflen > 0) {
		bsb(plen(term_buf[term_buflen-1]));
		term_buflen--;
		if (term_buflen > 0 &&
		    isspace(term_buf[term_buflen-1]) &&
		    !isspace(term_buf[term_buflen]))
		    break;
	    }
	    break;
	  case CTRL('U'):	       /* delete line */
	  case CTRL('C'):	       /* Send IP */
	  case CTRL('\\'):	       /* Quit */
	  case CTRL('Z'):	       /* Suspend */
	    while (term_buflen > 0) {
		bsb(plen(term_buf[term_buflen-1]));
		term_buflen--;
	    }
	    back->special (TS_EL);
	    if( c == CTRL('C') )  back->special (TS_IP);
	    if( c == CTRL('Z') )  back->special (TS_SUSP);
	    if( c == CTRL('\\') ) back->special (TS_ABORT);
            break;
	  case CTRL('R'):	       /* redraw line */
	    c_write("^R\r\n", 4);
	    {
		int i;
		for (i = 0; i < term_buflen; i++)
		    pwrite(term_buf[i]);
	    }
	    break;
	  case CTRL('V'):	       /* quote next char */
	    term_quotenext = TRUE;
	    break;
	  case CTRL('D'):	       /* logout or send */
	    if (term_buflen == 0) {
		back->special (TS_EOF);
	    } else {
		back->send(term_buf, term_buflen);
		term_buflen = 0;
	    }
	    break;
	  case CTRL('M'):	       /* send with newline */
	    if (term_buflen > 0)
                back->send(term_buf, term_buflen);
	    if (cfg.protocol == PROT_RAW)
	        back->send("\r\n", 2);
	    else
	        back->send("\r", 1);
	    c_write("\r\n", 2);
	    term_buflen = 0;
	    break;
	  default:                     /* get to this label from ^V handler */
	    if (term_buflen >= term_bufsiz) {
		term_bufsiz = term_buflen + 256;
		term_buf = saferealloc(term_buf, term_bufsiz);
	    }
	    term_buf[term_buflen++] = c;
	    pwrite(c);
            term_quotenext = FALSE;
	    break;
	}
    }
}
Пример #16
0
int
main(int argc, char *argv[]) {
	/* Command-line interface for CRC RevEng.
	 * Process options and switches in the argument list and
	 * run the required function.
	 */

	/* default values */
	model_t model = {
		PZERO,		/* no CRC polynomial, user must specify */
		PZERO,		/* Init = 0 */
		P_BE,		/* RefIn = false, RefOut = false, plus P_RTJUST setting in reveng.h */
		PZERO,		/* XorOut = 0 */
		PZERO,		/* check value unused */
		NULL		/* no model name */
	};
	int ibperhx = 8, obperhx = 8;
	int rflags = 0, uflags = 0; /* search and UI flags */

	unsigned long width = 0UL;
	int c, mode = 0, args, psets, pass;
	poly_t apoly, crc, qpoly = PZERO, *apolys, *pptr = NULL, *qptr = NULL;
	model_t pset = model, *candmods, *mptr;
	char *string;

	myname = argv[0];

	/* stdin must be binary */
#ifdef _WIN32
	_setmode(STDIN_FILENO, _O_BINARY);
#endif /* _WIN32 */

	SETBMP();

	do {
		c=getopt(argc, argv, "?A:BDFLMP:SVXa:bcdefhi:k:lm:p:q:rstuvw:x:y");
		switch(c) {
			case 'A': /* A: bits per output character */
			case 'a': /* a: bits per character */
				if((obperhx = atoi(optarg)) > BMP_BIT) {
					fprintf(stderr,"%s: argument to -%c must be between 1 and %d\n", myname, c, BMP_BIT);
					exit(EXIT_FAILURE);
				}
				if(c == 'a') ibperhx = obperhx;
				break;
			case 'b': /* b  big-endian (RefIn = false, RefOut = false ) */
				model.flags &= ~P_REFIN;
				rflags |= R_HAVERI;
				/* fall through: */
			case 'B': /* B  big-endian output (RefOut = false) */
				model.flags &= ~P_REFOUT;
				rflags |= R_HAVERO;
				mnovel(&model);
				/* fall through: */
			case 'r': /* r  right-justified */
				model.flags |= P_RTJUST;
				break;
			case 'c': /* c  calculate CRC */
			case 'D': /* D  list primary model names */
			case 'd': /* d  dump CRC model */
			case 'e': /* e  echo arguments */
			case 's': /* s  search for algorithm */
			case 'v': /* v  calculate reversed CRC */
				if(mode) {
					fprintf(stderr,"%s: more than one mode switch specified.  Use %s -h for help.\n", myname, myname);
					exit(EXIT_FAILURE);
				}
				mode = c;
				break;
			case 'F': /* F  force search */
#ifndef NOFORCE
				uflags |= C_FORCE;
#endif
				break;
			case 'f': /* f  arguments are filenames */
				uflags |= C_INFILE;
				break;
			case 'h': /* h  get help / usage */
			case 'u': /* u  get help / usage */
			case '?': /* ?  get help / usage */
			default:
				usage();
				exit(EXIT_FAILURE);
				break;
			case 'i': /* i: Init value */
				pptr = &model.init;
				rflags |= R_HAVEI;
				goto ippx;
			case 'k': /* k: polynomial in Koopman notation */
				pfree(&model.spoly);
				model.spoly = strtop(optarg, 0, 4);
				pkchop(&model.spoly);
				width = plen(model.spoly);
				rflags |= R_HAVEP;
				mnovel(&model);
				break;
			case 'l': /* l  little-endian input and output */
				model.flags |= P_REFIN;
				rflags |= R_HAVERI;
				/* fall through: */
			case 'L': /* L  little-endian output */
				model.flags |= P_REFOUT;
				rflags |= R_HAVERO;
				mnovel(&model);
				/* fall through: */
			case 't': /* t  left-justified */
				model.flags &= ~P_RTJUST;
				break;
			case 'm': /* m: select preset CRC model */
				if(!(c = mbynam(&model, optarg))) {
					fprintf(stderr,"%s: preset model '%s' not found.  Use %s -D to list presets.\n", myname, optarg, myname);
					exit(EXIT_FAILURE);
				}
				if(c < 0)
					uerror("no preset models available");
				/* must set width so that parameter to -ipx is not zeroed */
				width = plen(model.spoly);
				rflags |= R_HAVEP | R_HAVEI | R_HAVERI | R_HAVERO | R_HAVEX;
				break;
			case 'M': /* M  non-augmenting algorithm */
				model.flags &= ~P_MULXN;
				break;
			case 'P': /* P: reversed polynomial */
			case 'p': /* p: polynomial */
				pptr = &model.spoly;
				rflags &= ~R_HAVEQ;
				rflags |= R_HAVEP;
ippx:
				pfree(pptr);
				*pptr = strtop(optarg, 0, 4);
				pright(pptr, width);
				if(c == 'P')
					prev(pptr);
				mnovel(&model);
				break;
			case 'q': /* q: range end polynomial */
				pptr = &qpoly;
				rflags &= ~R_HAVEP;
				rflags |= R_HAVEQ;
				goto ippx;
			case 'S': /* s  space between output characters */
				model.flags |= P_SPACE;
				break;
			case 'V': /* v  reverse algorithm */
				/* Distinct from the -v switch as the
				 * user will have to reverse his or her
				 * own arguments.  The user cannot dump
				 * the model generated by -v either.
				 */
				mrev(&model);
				break;
			case 'w': /* w: CRC width = order - 1 */
				width = (unsigned long) atol(optarg);
				break;
			case 'X': /* X  print uppercase hex */
				model.flags |= P_UPPER;
				break;
			case 'x': /* x: XorOut value */
				pptr = &model.xorout;
				rflags |= R_HAVEX;
				goto ippx;
			case 'y': /* y  little-endian byte order in files */
				model.flags |= P_LTLBYT;
				break;
			case -1: /* no more options, continue */
				;
		}
	} while(c != -1);

	/* canonicalise the model, so the one we dump is the one we
	 * calculate with (not with -s, spoly may be blank which will
	 * normalise to zero and clear init and xorout.)
	 */
	if(mode != 's')
		mcanon(&model);

	switch(mode) {
		case 'v': /* v  calculate reversed CRC */
			/* Distinct from the -V switch as this causes
			 * the arguments and output to be reversed as well.
			 */
			/* reciprocate Poly */
			prcp(&model.spoly);

			/* mrev() does:
			 *   if(refout) prev(init); else prev(xorout);
			 * but here the entire argument polynomial is
			 * reflected, not just the characters, so RefIn
			 * and RefOut are not inverted as with -V.
			 * Consequently Init is the mirror image of the
			 * one resulting from -V, and so we have:
			 */
			if(~model.flags & P_REFOUT) {
				prev(&model.init);
				prev(&model.xorout);
			}

			/* swap init and xorout */
			apoly = model.init;
			model.init = model.xorout;
			model.xorout = apoly;

			/* fall through: */
		case 'c': /* c  calculate CRC */

			/* validate inputs */
			/* if(plen(model.spoly) == 0) {
			 *	fprintf(stderr,"%s: no polynomial specified for -%c (add -w WIDTH -p POLY)\n", myname, mode);
			 *	exit(EXIT_FAILURE);
			 * }
			 */

			/* in the Williams model, xorout is applied after the refout stage.
			 * as refout is part of ptostr(), we reverse xorout here.
			 */
			if(model.flags & P_REFOUT)
				prev(&model.xorout);

			for(; optind < argc; ++optind) {
				if(uflags & C_INFILE)
					apoly = rdpoly(argv[optind], model.flags, ibperhx);
				else
					apoly = strtop(argv[optind], model.flags, ibperhx);

				if(mode == 'v')
					prev(&apoly);

				crc = pcrc(apoly, model.spoly, model.init, model.xorout, model.flags);

				if(mode == 'v')
					prev(&crc);

				string = ptostr(crc, model.flags, obperhx);
				puts(string);
				free(string);
				pfree(&crc);
				pfree(&apoly);
			}
			break;
		case 'D': /* D  dump all models */
			args = mcount();
			if(!args)
				uerror("no preset models available");
			for(mode = 0; mode < args; ++mode) {
				mbynum(&model, mode);
				mcanon(&model);
				ufound(&model);
			}
			break;
		case 'd': /* d  dump CRC model */
			/* maybe we don't want to do this:
			 * either attaching names to arbitrary models or forcing to a preset
			 * mmatch(&model, M_OVERWR);
			 */
			if(~model.flags & P_MULXN)
				uerror("not a Williams model compliant algorithm");
			string = mtostr(&model);
			puts(string);
			free(string);
			break;
		case 'e': /* e  echo arguments */
			for(; optind < argc; ++optind) {
				if(uflags & C_INFILE)
					apoly = rdpoly(argv[optind], model.flags, ibperhx);
				else
					apoly = strtop(argv[optind], model.flags, ibperhx);

				psum(&apoly, model.init, 0UL);
				string = ptostr(apoly, model.flags, obperhx);
				puts(string);
				free(string);
				pfree(&apoly);
			}
			break;
		case 's': /* s  search for algorithm */
			if(!width)
				uerror("must specify positive -k or -w before -s");
			if(~model.flags & P_MULXN)
				uerror("cannot search for non-Williams compliant models");
			praloc(&model.spoly, width);
			praloc(&model.init, width);
			praloc(&model.xorout, width);
			if(!plen(model.spoly))
				palloc(&model.spoly, width);
			else
				width = plen(model.spoly);

			/* special case if qpoly is zero, search to end of range */
			if(!ptst(qpoly))
				rflags &= ~R_HAVEQ;

			/* allocate argument array */
			args = argc - optind;
			if(!(apolys = malloc(args * sizeof(poly_t))))
				uerror("cannot allocate memory for argument list");

			for(pptr = apolys; optind < argc; ++optind) {
				if(uflags & C_INFILE)
					*pptr++ = rdpoly(argv[optind], model.flags, ibperhx);
				else
					*pptr++ = strtop(argv[optind], model.flags, ibperhx);
			}
			/* exit value of pptr is used hereafter! */

			/* if endianness not specified, try
			 * little-endian then big-endian.
			 * NB: crossed-endian algorithms will not be
			 * searched.
			 */

			/* scan against preset models */
			if(~uflags & C_FORCE) {
				pass = 0;
				do {
					psets = mcount();
					while(psets) {
						mbynum(&pset, --psets);
						/* skip if different width, or refin or refout don't match */
						if(plen(pset.spoly) != width || (model.flags ^ pset.flags) & (P_REFIN | P_REFOUT))
							continue;
						/* skip if the preset doesn't match specified parameters */
						if(rflags & R_HAVEP && pcmp(&model.spoly, &pset.spoly))
							continue;
						if(rflags & R_HAVEI && psncmp(&model.init, &pset.init))
							continue;
						if(rflags & R_HAVEX && psncmp(&model.xorout, &pset.xorout))
							continue;
						apoly = pclone(pset.xorout);
						if(pset.flags & P_REFOUT)
							prev(&apoly);
						for(qptr = apolys; qptr < pptr; ++qptr) {
							crc = pcrc(*qptr, pset.spoly, pset.init, apoly, 0);
							if(ptst(crc)) {
								pfree(&crc);
								break;
							} else
								pfree(&crc);
						}
						pfree(&apoly);
						if(qptr == pptr) {
							/* the selected model solved all arguments */
							mcanon(&pset);
							ufound(&pset);
							uflags |= C_RESULT;
						}
					}
					mfree(&pset);

					/* toggle refIn/refOut and reflect arguments */
					if(~rflags & R_HAVERI) {
						model.flags ^= P_REFIN | P_REFOUT;
						for(qptr = apolys; qptr < pptr; ++qptr)
							prevch(qptr, ibperhx);
					}
				} while(~rflags & R_HAVERI && ++pass < 2);
			}
			if(uflags & C_RESULT) {
				for(qptr = apolys; qptr < pptr; ++qptr)
					pfree(qptr);
				exit(EXIT_SUCCESS);
			}
			if(!(model.flags & P_REFIN) != !(model.flags & P_REFOUT))
				uerror("cannot search for crossed-endian models");
			pass = 0;
			do {
				mptr = candmods = reveng(&model, qpoly, rflags, args, apolys);
				if(mptr && plen(mptr->spoly))
					uflags |= C_RESULT;
				while(mptr && plen(mptr->spoly)) {
					/* results were printed by the callback
					 * string = mtostr(mptr);
					 * puts(string);
					 * free(string);
					 */
					mfree(mptr++);
				}
				free(candmods);
				if(~rflags & R_HAVERI) {
					model.flags ^= P_REFIN | P_REFOUT;
					for(qptr = apolys; qptr < pptr; ++qptr)
						prevch(qptr, ibperhx);
				}
			} while(~rflags & R_HAVERI && ++pass < 2);
			for(qptr = apolys; qptr < pptr; ++qptr)
				pfree(qptr);
			free(apolys);
			if(~uflags & C_RESULT)
				uerror("no models found");
			break;
		default:  /* no mode specified */
			fprintf(stderr, "%s: no mode switch specified. Use %s -h for help.\n", myname, myname);
			exit(EXIT_FAILURE);
	}

	exit(EXIT_SUCCESS);
}