/* * Define the printing format for control (or binary utf) chars. */ static void setbinfmt(char *e, const char **fmtvarptr, const char *default_fmt) { const char *s; if (((s = lgetenv(e)) == NULL) || (*s == 0)) { s = default_fmt; goto attr; } if (s != NULL && *s != 0) { if (checkfmt(s) < 0) { s = default_fmt; goto attr; } } /* * Select the attributes if it starts with "*". */ attr: if (*s == '*') { switch (s[1]) { case 'd': binattr = AT_BOLD; break; case 'k': binattr = AT_BLINK; break; case 's': binattr = AT_STANDOUT; break; case 'u': binattr = AT_UNDERLINE; break; default: binattr = AT_NORMAL; break; } s += 2; } *fmtvarptr = s; }
SEXP attribute_hidden do_sprintf(SEXP call, SEXP op, SEXP args, SEXP env) { int i, nargs, cnt, v, thislen, nfmt, nprotect = 0; /* fmt2 is a copy of fmt with '*' expanded. bit will hold numeric formats and %<w>s, so be quite small. */ char fmt[MAXLINE+1], fmt2[MAXLINE+10], *fmtp, bit[MAXLINE+1], *outputString; const char *formatString; size_t n, cur, chunk; SEXP format, _this, a[MAXNARGS], ans /* -Wall */ = R_NilValue; int ns, maxlen, lens[MAXNARGS], nthis, nstar, star_arg = 0; static R_StringBuffer outbuff = {NULL, 0, MAXELTSIZE}; Rboolean has_star, use_UTF8; #define _my_sprintf(_X_) \ { \ int nc = snprintf(bit, MAXLINE+1, fmtp, _X_); \ if (nc > MAXLINE) \ error(_("required resulting string length %d is greater than maximal %d"), \ nc, MAXLINE); \ } nargs = length(args); /* grab the format string */ format = CAR(args); if (!isString(format)) error(_("'fmt' is not a character vector")); nfmt = length(format); if (nfmt == 0) return allocVector(STRSXP, 0); args = CDR(args); nargs--; if(nargs >= MAXNARGS) error(_("only %d arguments are allowed"), MAXNARGS); /* record the args for possible coercion and later re-ordering */ for(i = 0; i < nargs; i++, args = CDR(args)) { SEXPTYPE t_ai; a[i] = CAR(args); if((t_ai = TYPEOF(a[i])) == LANGSXP || t_ai == SYMSXP) /* << maybe add more .. */ error(_("invalid type of argument[%d]: '%s'"), i+1, CHAR(type2str(t_ai))); lens[i] = length(a[i]); if(lens[i] == 0) return allocVector(STRSXP, 0); } #define CHECK_maxlen \ maxlen = nfmt; \ for(i = 0; i < nargs; i++) \ if(maxlen < lens[i]) maxlen = lens[i]; \ if(maxlen % nfmt) \ error(_("arguments cannot be recycled to the same length")); \ for(i = 0; i < nargs; i++) \ if(maxlen % lens[i]) \ error(_("arguments cannot be recycled to the same length")) CHECK_maxlen; outputString = R_AllocStringBuffer(0, &outbuff); /* We do the format analysis a row at a time */ for(ns = 0; ns < maxlen; ns++) { outputString[0] = '\0'; use_UTF8 = getCharCE(STRING_ELT(format, ns % nfmt)) == CE_UTF8; if (!use_UTF8) { for(i = 0; i < nargs; i++) { if (!isString(a[i])) continue; if (getCharCE(STRING_ELT(a[i], ns % lens[i])) == CE_UTF8) { use_UTF8 = TRUE; break; } } } formatString = TRANSLATE_CHAR(format, ns % nfmt); n = strlen(formatString); if (n > MAXLINE) error(_("'fmt' length exceeds maximal format length %d"), MAXLINE); /* process the format string */ for (cur = 0, cnt = 0; cur < n; cur += chunk) { const char *curFormat = formatString + cur, *ss; char *starc; ss = NULL; if (formatString[cur] == '%') { /* handle special format command */ if (cur < n - 1 && formatString[cur + 1] == '%') { /* take care of %% in the format */ chunk = 2; strcpy(bit, "%"); } else { /* recognise selected types from Table B-1 of K&R */ /* NB: we deal with "%%" in branch above. */ /* This is MBCS-OK, as we are in a format spec */ chunk = strcspn(curFormat + 1, "diosfeEgGxXaA") + 2; if (cur + chunk > n) error(_("unrecognised format specification '%s'"), curFormat); strncpy(fmt, curFormat, chunk); fmt[chunk] = '\0'; nthis = -1; /* now look for %n$ or %nn$ form */ if (strlen(fmt) > 3 && fmt[1] >= '1' && fmt[1] <= '9') { v = fmt[1] - '0'; if(fmt[2] == '$') { if(v > nargs) error(_("reference to non-existent argument %d"), v); nthis = v-1; memmove(fmt+1, fmt+3, strlen(fmt)-2); } else if(fmt[2] >= '0' && fmt[2] <= '9' && fmt[3] == '$') { v = 10*v + fmt[2] - '0'; if(v > nargs) error(_("reference to non-existent argument %d"), v); nthis = v-1; memmove(fmt+1, fmt+4, strlen(fmt)-3); } } starc = Rf_strchr(fmt, '*'); if (starc) { /* handle * format if present */ nstar = -1; if (strlen(starc) > 3 && starc[1] >= '1' && starc[1] <= '9') { v = starc[1] - '0'; if(starc[2] == '$') { if(v > nargs) error(_("reference to non-existent argument %d"), v); nstar = v-1; memmove(starc+1, starc+3, strlen(starc)-2); } else if(starc[2] >= '0' && starc[2] <= '9' && starc[3] == '$') { v = 10*v + starc[2] - '0'; if(v > nargs) error(_("reference to non-existent argument %d"), v); nstar = v-1; memmove(starc+1, starc+4, strlen(starc)-3); } } if(nstar < 0) { if (cnt >= nargs) error(_("too few arguments")); nstar = cnt++; } if (Rf_strchr(starc+1, '*')) error(_("at most one asterisk '*' is supported in each conversion specification")); _this = a[nstar]; if(ns == 0 && TYPEOF(_this) == REALSXP) { _this = coerceVector(_this, INTSXP); PROTECT(a[nstar] = _this); nprotect++; } if(TYPEOF(_this) != INTSXP || LENGTH(_this)<1 || INTEGER(_this)[ns % LENGTH(_this)] == NA_INTEGER) error(_("argument for '*' conversion specification must be a number")); star_arg = INTEGER(_this)[ns % LENGTH(_this)]; has_star = TRUE; } else has_star = FALSE; if (fmt[strlen(fmt) - 1] == '%') { /* handle % with formatting options */ if (has_star) snprintf(bit, MAXLINE+1, fmt, star_arg); else strcpy(bit, fmt); /* was sprintf(..) for which some compiler warn */ } else { Rboolean did_this = FALSE; if(nthis < 0) { if (cnt >= nargs) error(_("too few arguments")); nthis = cnt++; } _this = a[nthis]; if (has_star) { size_t nf; char *p, *q = fmt2; for (p = fmt; *p; p++) if (*p == '*') q += sprintf(q, "%d", star_arg); else *q++ = *p; *q = '\0'; nf = strlen(fmt2); if (nf > MAXLINE) error(_("'fmt' length exceeds maximal format length %d"), MAXLINE); fmtp = fmt2; } else fmtp = fmt; #define CHECK_this_length \ PROTECT(_this); \ thislen = length(_this); \ if(thislen == 0) \ error(_("coercion has changed vector length to 0")) /* Now let us see if some minimal coercion would be sensible, but only do so once, for ns = 0: */ if(ns == 0) { SEXP tmp; Rboolean do_check; switch(*findspec(fmtp)) { case 'd': case 'i': case 'o': case 'x': case 'X': if(TYPEOF(_this) == REALSXP) { double r = REAL(_this)[0]; if((double)((int) r) == r) _this = coerceVector(_this, INTSXP); PROTECT(a[nthis] = _this); nprotect++; } break; case 'a': case 'A': case 'e': case 'f': case 'g': case 'E': case 'G': if(TYPEOF(_this) != REALSXP && /* no automatic as.double(<string>) : */ TYPEOF(_this) != STRSXP) { PROTECT(tmp = lang2(install("as.double"), _this)); #define COERCE_THIS_TO_A \ _this = eval(tmp, env); \ UNPROTECT(1); \ PROTECT(a[nthis] = _this); \ nprotect++; \ did_this = TRUE; \ CHECK_this_length; \ do_check = (lens[nthis] == maxlen); \ lens[nthis] = thislen; /* may have changed! */ \ if(do_check && thislen < maxlen) { \ CHECK_maxlen; \ } COERCE_THIS_TO_A } break; case 's': if(TYPEOF(_this) != STRSXP) { /* as.character method might call sprintf() */ size_t nc = strlen(outputString); char *z = Calloc(nc+1, char); strcpy(z, outputString); PROTECT(tmp = lang2(install("as.character"), _this)); COERCE_THIS_TO_A strcpy(outputString, z); Free(z); } break; default: break; } } /* ns == 0 (first-time only) */ if(!did_this) CHECK_this_length; switch(TYPEOF(_this)) { case LGLSXP: { int x = LOGICAL(_this)[ns % thislen]; if (checkfmt(fmtp, "di")) error(_("invalid format '%s'; %s"), fmtp, _("use format %d or %i for logical objects")); if (x == NA_LOGICAL) { fmtp[strlen(fmtp)-1] = 's'; _my_sprintf("NA") } else { _my_sprintf(x) } break; } case INTSXP: { int x = INTEGER(_this)[ns % thislen]; if (checkfmt(fmtp, "dioxX")) error(_("invalid format '%s'; %s"), fmtp, _("use format %d, %i, %o, %x or %X for integer objects")); if (x == NA_INTEGER) { fmtp[strlen(fmtp)-1] = 's'; _my_sprintf("NA") } else { _my_sprintf(x) } break; }
/* ------------------------------------------------------------------ */ static int parse_commandline(int argc, char **argv) { int i, nargc , nargsused; char **pargv, *option ; char tmpstr[1000]; if (argc < 1) usage_exit(); nargc = argc; pargv = argv; while (nargc > 0) { option = pargv[0]; if (debug) printf("%d %s\n",nargc,option); nargc -= 1; pargv += 1; nargsused = 0; if (!strcasecmp(option, "--help")) print_help() ; else if (!strcasecmp(option, "--version")) print_version() ; else if (!strcasecmp(option, "--debug")) debug = 1; else if (!strcasecmp(option, "--abs")) DoAbs = 1; else if (!strcasecmp(option, "--nogmnnorm")) gmnnorm = 0; else if (!strcasecmp(option, "--rescale")) rescale=1; else if (!strcasecmp(option, "--norescale")) rescale=0; else if (!strcasecmp(option, "--no-output")) NoOutput = 1; else if (!strcasecmp(option, "--fft")) UseFFT = 1; else if (!strcasecmp(option, "--offset")) AddOffset=1; else if (!strcasecmp(option, "--offset-mid")){ AddOffset = 1; OffsetFrame = -1; } else if (!strcmp(option, "--hsc")) { if (nargc < 2) argnerr(option,2); sscanf(pargv[0],"%lf",&HSCMin); sscanf(pargv[1],"%lf",&HSCMax); DoHSC = 1; nargsused = 2; } else if (!strcmp(option, "--sum2")) { if (nargc < 1) argnerr(option,1); sum2file = pargv[0]; pdfname = "delta"; //NoOutput = 1; nframes = 1; nargsused = 1; } else if (!strcmp(option, "--hsynth")) { // eres mask DoTnorm out if (nargc < 3) argnerr(option,3); mri = MRIread(pargv[0]); mask = MRIread(pargv[1]); sscanf(pargv[2],"%d",&DoTNorm); mri2 = fMRIhsynth(mri, mask, DoTNorm); MRIwrite(mri2,pargv[3]); exit(0); nargsused = 2; } else if (!strcmp(option, "--vol") || !strcmp(option, "--o")) { if (nargc < 1) argnerr(option,1); volid = pargv[0]; nargsused = 1; if (nth_is_arg(nargc, pargv, 1)) { volfmt = pargv[1]; nargsused ++; volfmtid = checkfmt(volfmt); } } else if (!strcmp(option, "--temp") || !strcmp(option, "--template")) { if(DoCurv){ printf("ERROR: cannot use --temp and --curv\n"); exit(1); } if(nargc < 1) argnerr(option,1); tempid = pargv[0]; nargsused = 1; if (nth_is_arg(nargc, pargv, 1)) { tempfmt = pargv[1]; nargsused ++; tempfmtid = checkfmt(tempfmt); } else tempfmtid = getfmtid(tempid); } else if (!strcmp(option, "--curv")) { if(tempid != NULL){ printf("ERROR: cannot use --temp and --curv\n"); exit(1); } if(nargc < 2) argnerr(option,2); subject = pargv[0]; hemi = pargv[1]; DoCurv = 1; nargsused = 2; sprintf(tmpstr,"%s/%s/surf/%s.thickness",getenv("SUBJECTS_DIR"),subject,hemi); tempid = strcpyalloc(tmpstr); } else if ( !strcmp(option, "--dim") ) { if (nargc < 4) argnerr(option,4); for (i=0;i<4;i++) sscanf(pargv[i],"%d",&dim[i]); nargsused = 4; dimSpeced = 1; } else if ( !strcmp(option, "--nframes") ) { if (nargc < 1) argnerr(option,1); sscanf(pargv[0],"%d",&nframes); nargsused = 1; } else if ( !strcmp(option, "--TR") || !strcmp(option, "--tr") ) { if (nargc < 1) argnerr(option,1); sscanf(pargv[0],"%lf",&TR); nargsused = 1; } else if ( !strcmp(option, "--res") ) { if (nargc < 4) argnerr(option,4); for (i=0;i<4;i++) sscanf(pargv[i],"%f",&res[i]); nargsused = 4; resSpeced = 1; } else if ( !strcmp(option, "--vox-size") ) { if (nargc < 3) argnerr(option,3); for (i=0;i<3;i++) sscanf(pargv[i],"%f",&res[i]); nargsused = 4; resSpeced = 1; NewVoxSizeSpeced = 1; } else if ( !strcmp(option, "--c_ras") ) { if (nargc < 3) argnerr(option,3); for (i=0;i<3;i++) sscanf(pargv[i],"%f",&cras[i]); nargsused = 3; } else if ( !strcmp(option, "--p0") ) { if (nargc < 3) argnerr(option,3); for (i=0;i<3;i++) sscanf(pargv[i],"%f",&p0[i]); usep0 = 1; nargsused = 3; } else if ( !strcmp(option, "--cdircos") ) { if (nargc < 3) argnerr(option,3); for (i=0;i<3;i++) sscanf(pargv[i],"%f",&cdircos[i]); nargsused = 3; } else if ( !strcmp(option, "--rdircos") ) { if (nargc < 3) argnerr(option,3); for (i=0;i<3;i++) sscanf(pargv[i],"%f",&rdircos[i]); nargsused = 3; } else if ( !strcmp(option, "--sdircos") ) { if (nargc < 3) argnerr(option,3); for (i=0;i<3;i++) sscanf(pargv[i],"%f",&sdircos[i]); nargsused = 3; } else if ( !strcmp(option, "--fwhm") ) { if (nargc < 1) argnerr(option,1); sscanf(pargv[0],"%f",&fwhm); gstd = fwhm/sqrt(log(256.0)); nargsused = 1; } else if (!strcmp(option, "--precision")) { if (nargc < 1) argnerr(option,1); precision = pargv[0]; nargsused = 1; } else if (!strcmp(option, "--seed")) { if (nargc < 1) argnerr(option,1); sscanf(pargv[0],"%ld",&seed); nargsused = 1; } else if (!strcmp(option, "--seedfile")) { if (nargc < 1) argnerr(option,1); seedfile = pargv[0]; nargsused = 1; } else if (!strcmp(option, "--pdf")) { if (nargc < 1) argnerr(option,1); pdfname = pargv[0]; nargsused = 1; } else if (!strcmp(option, "--bb")) { if (nargc < 6) argnerr(option,6); sscanf(pargv[0],"%d",&boundingbox.x); sscanf(pargv[1],"%d",&boundingbox.y); sscanf(pargv[2],"%d",&boundingbox.z); sscanf(pargv[3],"%d",&boundingbox.dx); sscanf(pargv[4],"%d",&boundingbox.dy); sscanf(pargv[5],"%d",&boundingbox.dz); pdfname = "boundingbox"; nargsused = 6; } else if (!strcasecmp(option, "--checker")) pdfname = "checker"; else if (!strcmp(option, "--dof-num")) { if (nargc < 1) argnerr(option,1); sscanf(pargv[0],"%d",&numdof); nargsused = 1; } else if (!strcmp(option, "--val-a")) { if (nargc < 1) argnerr(option,1); sscanf(pargv[0],"%lf",&ValueA); nargsused = 1; } else if (!strcmp(option, "--val-b")) { if (nargc < 1) argnerr(option,1); sscanf(pargv[0],"%lf",&ValueB); nargsused = 1; } else if (!strcmp(option, "--radius")) { if (nargc < 1) argnerr(option,1); sscanf(pargv[0],"%lf",&voxradius); nargsused = 1; } else if (!strcmp(option, "--dof-den") || !strcmp(option, "--dof")) { if (nargc < 1) argnerr(option,1); sscanf(pargv[0],"%d",&dendof); nargsused = 1; } else if (!strcmp(option, "--gmean")) { if (nargc < 1) argnerr(option,1); sscanf(pargv[0],"%lf",&gausmean); nargsused = 1; } else if (!strcmp(option, "--gstd")) { if (nargc < 1) argnerr(option,1); sscanf(pargv[0],"%lf",&gausstd); nargsused = 1; } else if (!strcmp(option, "--delta-crsf")) { if (nargc < 4) argnerr(option,4); sscanf(pargv[0],"%d",&delta_crsf[0]); sscanf(pargv[1],"%d",&delta_crsf[1]); sscanf(pargv[2],"%d",&delta_crsf[2]); sscanf(pargv[3],"%d",&delta_crsf[3]); delta_crsf_speced = 1; nargsused = 4; } else if (!strcmp(option, "--delta-val")) { if (nargc < 1) argnerr(option,1); sscanf(pargv[0],"%lf",&delta_value); nargsused = 1; } else if (!strcmp(option, "--delta-val-off")) { if (nargc < 1) argnerr(option,1); sscanf(pargv[0],"%lf",&delta_off_value); nargsused = 1; } else if (!strcmp(option, "--spike")) { if (nargc < 1) argnerr(option,1); sscanf(pargv[0],"%d",&SpikeTP); nargsused = 1; } else { fprintf(stderr,"ERROR: Option %s unknown\n",option); if (singledash(option)) fprintf(stderr," Did you really mean -%s ?\n",option); exit(-1); } nargc -= nargsused; pargv += nargsused; } return(0); }