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; }
// (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; }
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); }
// (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; }
//两圆相交的面积 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; }
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); }
// (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); }
// (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); }
// (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)); }
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); }
// (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 }
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); } } }
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; } }
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; } } }
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); }