void annotate(void) { char buf[64]; int ypos, xpos; glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho((GLdouble) 0, (GLdouble) wscreen, (GLdouble) hscreen, (GLdouble) 0, (GLdouble) -1.0, (GLdouble) 1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glPushMatrix(); glColor3f(RVAL(0xffffff), GVAL(0xffffff), BVAL(0xffffff)); if (actval == -1) { if (! strnull(getparam("ident"))) showtext(getparam("ident"), 10, 20); sprintf(buf, "%.2f", tnow); showtext(buf, wscreen - (8 * strlen(buf) + 10), 20); } else { ypos = hscreen - 10; if (vectoroff != -1) { sprintf(buf, "vector scale: %.2f", vscale); showtext(buf, 10, ypos); ypos -= 20; } if (scalaroff != -1 || dopcolor) { xpos = 10; sprintf(buf, "mapping: "); showtext(buf, xpos, ypos); xpos += 8 * strlen(buf); sprintf(buf, "%.2f", cmidpt + crange); glColor3f(RVAL(0x0000ff), GVAL(0x0000ff), BVAL(0x0000ff)); showtext(buf, xpos, ypos); xpos += 8 * strlen(buf); glColor3f(RVAL(0xffffff), GVAL(0xffffff), BVAL(0xffffff)); showtext(" to ", xpos, ypos); xpos += 32; sprintf(buf, "%.2f", cmidpt - crange); glColor3f(RVAL(0xff4f00), GVAL(0xff4f00), BVAL(0xff4f00)); showtext(buf, xpos, ypos); xpos += 8 * strlen(buf); ypos -= 20; glColor3f(RVAL(0xffffff), GVAL(0xffffff), BVAL(0xffffff)); } sprintf(buf, "angles: %.2f, %.2f, %.2f", thetax, thetay, thetaz); showtext(buf, 10, ypos); ypos -= 20; sprintf(buf, "view: %.2f, %.2f, %.2f; %.2f", xoff, yoff, dview, fview); showtext(buf, 10, ypos); ypos -= 20; } glPopMatrix(); }
void render(void) { int step, oldc, newc; bodyptr bp; float cval; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective((GLdouble) fview, (GLdouble) ((double) wscreen) / hscreen, (GLdouble) 0.01 * dview, (GLdouble) 100.0 * dview); glGetFloatv(GL_PROJECTION_MATRIX, &projmat[0][0]); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); glTranslatef(xoff, yoff, -dview); glRotatef(-thetaz, 0.0, 0.0, 1.0); /* same map as snaprotate */ glRotatef(-thetay, 0.0, 1.0, 0.0); glRotatef(-thetax, 1.0, 0.0, 0.0); glGetFloatv(GL_MODELVIEW_MATRIX, &viewmat[0][0]); glBegin(vectoroff == -1 ? GL_POINTS : GL_LINES); step = (actval == -1 ? 1 : rceil((float) nbody / (float) maxfast)); oldc = -1; for (bp = btab; bp < NthBody(btab, nbody); bp = NthBody(bp, step)) { if (scalaroff == -1 && ! dopcolor) newc = Key(bp); else { if (! dopcolor) cval = (SelectReal(bp, scalaroff) - cmidpt) / crange; else cval = (dotvp(Vel(bp), znorm) - cmidpt) / crange; newc = (cval > 1.0 ? 0x0000ff : cval > 0.6 ? 0x006fdf : cval > 0.2 ? 0x00cf7f : cval > -0.2 ? 0x00ff00 : cval > -0.6 ? 0x7fcf00 : cval > -1.0 ? 0xbf8f00 : 0xff4f00); } if (oldc != newc) glColor3f(RVAL(newc), GVAL(newc), BVAL(newc)); oldc = newc; glVertex3f(Pos(bp)[0], Pos(bp)[1], Pos(bp)[2]); if (vectoroff != -1) glVertex3f(Pos(bp)[0] + vscale * SelectVect(bp, vectoroff)[0], Pos(bp)[1] + vscale * SelectVect(bp, vectoroff)[1], Pos(bp)[2] + vscale * SelectVect(bp, vectoroff)[2]); } glEnd(); if (actval != -1) { glColor3f(RVAL(bcolor), GVAL(bcolor), BVAL(bcolor)); glutWireCube(refscale); } glPopMatrix(); }
Status va_deep_copy_value(Value value, Value *new_val) { if (!STR_BASED_VAL(value)) { *new_val = value; return STATUS_SUCCESS; } const char *curr_val = va_str_val(value); if (curr_val == NULL) { *new_val = value; return STATUS_SUCCESS; } char *str_val = strdup(curr_val); if (str_val == NULL) { return OUT_OF_MEMORY("Unable to copy value"); } if (value.type == VAL_TYPE_STR) { *new_val = STR_VAL(str_val); } else if (value.type == VAL_TYPE_REGEX) { *new_val = REGEX_VAL(str_val, RVAL(value).modifiers); } else if (value.type == VAL_TYPE_SHELL_COMMAND) { *new_val = CMD_VAL(str_val); } return STATUS_SUCCESS; }
void canblend(canvas *dst, canvas *src, float fr, float fg, float fb, float fa) { if(!cansizecheck(dst, src, "canmult: canvases must be the same size\n")) return; unsigned int *dptr = dst->data; unsigned int *sptr = src->data; int npix = dst->sizex*dst->sizey; while(npix--) { float fas = fa*AVAL(*sptr)/255.0; int rd = round(fr*RVAL(*sptr) + (1.0-fas)*RVAL(*dptr)); int gd = round(fg*GVAL(*sptr) + (1.0-fas)*GVAL(*dptr)); int bd = round(fb*BVAL(*sptr) + (1.0-fas)*BVAL(*dptr)); int ad = round(fa*AVAL(*sptr) + (1.0-fas)*AVAL(*dptr)); *dptr++ = CPACK(rd, gd, bd, ad); sptr++; } }
void canmult(canvas *a, canvas *b) { if(!cansizecheck(a, b, "canmult: canvases must be the same size\n")) return; int npix = a->sizex*a->sizey; unsigned int *aptr = a->data; unsigned int *bptr = b->data; while(npix--) { int ir = round(RVAL(*aptr)*RVAL(*bptr)/255.0); int ig = round(GVAL(*aptr)*GVAL(*bptr)/255.0); int ib = round(BVAL(*aptr)*BVAL(*bptr)/255.0); int ia = round(AVAL(*aptr)*AVAL(*bptr)/255.0); *aptr = CPACK(ir,ig,ib,ia); aptr++; bptr++; } }
void Sensor::printCurrent() { #else void Sensor::printCurrent() { #endif Serial.print(F("FL:")); Serial.print(RVAL(sC::FL)); Serial.print(F("\t")); Serial.print(F("LTL:")); Serial.print(RVAL(sC::LTL)); Serial.print(F("\t")); Serial.print(F("LTR:")); Serial.print(RVAL(sC::LTR)); Serial.print(F("\t")); Serial.print(F("FR:")); Serial.print(RVAL(sC::FR)); Serial.println(F("\t")); Serial.print(F("ML:")); Serial.print(RVAL(sC::ML)); Serial.print(F("\t")); Serial.print(F("\t")); Serial.print(F("MR:")); Serial.print(RVAL(sC::MR)); Serial.println(F("\t")); Serial.print(F("BL:")); Serial.print(RVAL(sC::BL)); Serial.print(F("\t")); Serial.print(F("\t")); Serial.print(F("BR:")); Serial.print(RVAL(sC::BR)); Serial.println(F("\t")); }
void canscalergba(canvas *c, float r, float g, float b, float a) { int npix = c->sizex*c->sizey; unsigned int *lptr = c->data; while(npix--) { int ir = round(r*RVAL(*lptr)); int ig = round(g*GVAL(*lptr)); int ib = round(b*BVAL(*lptr)); int ia = round(a*AVAL(*lptr)); *lptr++ = CPACK(ir,ig,ib,ia); } }
void cansaturate(canvas *c, float sat) { int npix = c->sizex*c->sizey; unsigned int *lptr = c->data; while(npix--) { int r = RVAL(*lptr); int g = GVAL(*lptr); int b = BVAL(*lptr); int lum = ILUM(r,g,b); *lptr++ = CPACK(pixlerp(lum,r,sat),pixlerp(lum,g,sat),pixlerp(lum,b,sat),255); } }
void Sensor::printbw() { #else void Sensor::printbw() { #endif //Print sensor outputs #ifdef SENSOR_DEBUG Serial.print(F("FL:")); Serial.print(RVAL(sC::FL)); Serial.print(F("\t")); Serial.print(F("LTL:")); Serial.print(RVAL(sC::LTL)); Serial.print(F("\t")); Serial.print(F("LTR:")); Serial.print(RVAL(sC::LTR)); Serial.print(F("\t")); Serial.print(F("FR:")); Serial.print(RVAL(sC::FR)); Serial.println(F("\t")); Serial.print(F("ML:")); Serial.print(RVAL(sC::ML)); Serial.print(F("\t")); Serial.print(F("\t")); Serial.print(F("MR:")); Serial.print(RVAL(sC::MR)); Serial.println(F("\t")); Serial.print(F("BL:")); Serial.print(RVAL(sC::BL)); Serial.print(F("\t")); Serial.print(F("\t")); Serial.print(F("BR:")); Serial.print(RVAL(sC::BR)); Serial.println(F("\t")); #endif }
void va_free_value(Value value) { if (!STR_BASED_VAL(value)) { return; } if (value.type == VAL_TYPE_STR) { free(SVAL(value)); } else if (value.type == VAL_TYPE_REGEX) { free(RVAL(value).regex_pattern); } else if (value.type == VAL_TYPE_SHELL_COMMAND) { free(CVAL(value)); } }
const char *va_str_val(Value value) { if (value.type == VAL_TYPE_STR) { return SVAL(value); } else if (value.type == VAL_TYPE_REGEX) { return RVAL(value).regex_pattern; } else if (value.type == VAL_TYPE_SHELL_COMMAND) { return CVAL(value); } assert(!"Invalid value type"); return NULL; }
/* * XRDBLE. Get double precision real parameters/variables. */ FUNCTION VOID BRIDGE2_NAME(xrdble) ( TAEINT *block, /* in: parameter block */ FORSTR *name, /* in: parameter name */ TAEINT *dimen, /* in: max # of values(dim of intg) */ TAEFLOAT dble[], /* out: array with real var */ TAEINT *n, /* out: real value count */ TAEINT *status /* out: status code */ ) { IMPORT TEXT pm_dim[],pk_dim[],pm_type[],pk_type[]; struct PARBLK *parblk; struct VARIABLE *v; TEXT c_name[STRINGSIZ+1]; /* name in C string format */ COUNT i; parblk = (struct PARBLK *) block; s_for2c(name, c_name, 0); /* convert name to C string */ s_strip(c_name); /* remove trailing blanks */ *n = 0; /* caution in case error */ v = p_find(parblk, c_name); if (v == NULL) goto p__bnerr; if ((*v).v_type != V_REAL) goto p__bterr; if ((*v).v_count > *dimen) goto p__bcerr; *n = (*v).v_count; for (i = 0; i < (*v).v_count; i++) dble[i] = RVAL(*v, i); *status = SUCCESS; return; p__bnerr: *status = P_BADNAME; return; p__bterr: *status = P_BADTYPE; x_error((*parblk).mode, pm_type, pk_type, (uintptr_t) c_name, 0, 0); return; p__bcerr: *status = P_BADCOUNT; x_error((*parblk).mode, pm_dim, pk_dim, (uintptr_t) c_name, 0, 0); return; }
// // Update the interrupt line according to the IntStatus register // static void updateInterrupt() { Bool interruptActive = (RVAL(IntStatus) != 0); // Has interrupt changed? if (interruptState != interruptActive) { ppmWriteNet(handles.Interrupt, interruptActive); interruptState = interruptActive; if (DIAG_HIGH) { bhmMessage( "I", PREFIX"_INT", "Interrupt %s", interruptState ? "set" : "cleared" ); } } }
char *va_to_string(Value value) { switch (value.type) { case VAL_TYPE_STR: return strdup(SVAL(value)); case VAL_TYPE_BOOL: return strdup(IVAL(value) ? "true" : "false"); case VAL_TYPE_INT: { char *num_str = malloc(VALUE_STR_CONVERT_SIZE); if (num_str == NULL) { return NULL; } snprintf(num_str, VALUE_STR_CONVERT_SIZE, "%ld", IVAL(value)); return num_str; } case VAL_TYPE_FLOAT: { char *num_str = malloc(VALUE_STR_CONVERT_SIZE); if (num_str == NULL) { return NULL; } snprintf(num_str, VALUE_STR_CONVERT_SIZE, "%f", FVAL(value)); return num_str; } case VAL_TYPE_REGEX: return strdup(RVAL(value).regex_pattern); case VAL_TYPE_SHELL_COMMAND: return strdup(CVAL(value)); default: assert(!"Invalid value type"); break; } return NULL; }
//Polls all given sensors in the order specified. void Sensor::PollSensors(Sensor *sens, const sC::sensorNumber *order, const byte OrderLength){ if (_sensorInitComplete == false) { ERROR_PRINTLN("Please call initSensors() before attempting to poll"); return; } sC::sensorNumber currentSensorIndex = sC::FR; for (byte n = 0; n < OrderLength; n++) { currentSensorIndex = order[n]; SelectSensor(static_cast<byte>(currentSensorIndex)); SLASTVAL(currentSensorIndex, RVAL(currentSensorIndex)); sens[currentSensorIndex].GetReading(); SVAL(currentSensorIndex, sens[currentSensorIndex].tileWhite); } printbw(); }
int cantofile(canvas *c, const char *outfilename) { FILE *fptr = fopen(outfilename, "wb"); if(!fptr) { fprintf(stderr, " Error: cantofile: can't open output file\n"); fprintf(stderr, " [%s]\n",outfilename); return 0; } int sizex = c->sizex; int sizey = c->sizey; // from http://paulbourke.net/dataformats/tga/ putc(0,fptr); putc(0,fptr); putc(2,fptr); /* uncompressed RGB */ putc(0,fptr); putc(0,fptr); putc(0,fptr); putc(0,fptr); putc(0,fptr); putc(0,fptr); putc(0,fptr); /* X origin */ putc(0,fptr); putc(0,fptr); /* y origin */ putc((sizex & 0x00FF),fptr); putc((sizex & 0xFF00) / 256,fptr); putc((sizey & 0x00FF),fptr); putc((sizey & 0xFF00) / 256,fptr); putc(32,fptr); /* 32 bit bitmap */ putc(0,fptr); for(int y=0; y<sizey; y++) { unsigned int *lptr = c->data+((sizey-1-y)*sizex); for(int x=0; x<sizex; x++) { putc(BVAL(*lptr),fptr); putc(GVAL(*lptr),fptr); putc(RVAL(*lptr),fptr); putc(AVAL(*lptr),fptr); lptr++; } } fclose(fptr); return 1; }
// set channel value to one endpoint (also to middle with 3-pos CH3) static void kf_set_switch(u8 *id, u8 *param, u8 flags, s16 *prev_val) { u8 *name = param ? param : id; et_functions_s *etf = menu_et_function_find_name(name); s16 val; if (!etf) return; RVAL(val); if (flags & FF_MID) { // middle if (flags & FF_PREVIOUS) val = *prev_val; else val = etf->reset; } else if (flags & FF_ON) { // ON *prev_val = val; // always save previous val val = (s8)(flags & FF_REVERSE ? etf->min : etf->max); } else { // OFF if ((flags & FF_PREVIOUS) && !(flags & FF_HAS_MID)) // use previous only when there is no middle state val = *prev_val; else { // save previous only when there is middle state if (flags & FF_HAS_MID) *prev_val = val; val = (s8)(flags & FF_REVERSE ? etf->max : etf->min); } } AVAL(val); if (flags & FF_SHOW) { menu_et_function_show_id(etf); lcd_char_num3(val); } }
static u8 menu_popup_et(u8 trim_id) { u16 delay_time; s16 val; u8 step; u16 buttons_state_last; u16 btn_l = ETB_L(trim_id); u16 btn_r = ETB_R(trim_id); u16 btn_lr = btn_l | btn_r; config_et_map_s *etm = &ck.et_map[trim_id]; #define SF_ROTATE etm->rotate et_functions_s *etf = &et_functions[etm->function]; u8 *mbs = &menu_buttons_state[NUM_KEYS + 2 * trim_id]; // read value RVAL(val); // remember buttons state buttons_state_last = buttons_state & ~btn_lr; // handle momentary keys // when something changed, show value for 5s while checking buttons // during initialize show nothing if (etm->buttons == ETB_MOMENTARY) { s16 *pv = &menu_buttons_previous_values[NUM_KEYS + 2 * trim_id]; u8 value_showed = 0; u8 state; while (1) { // set actual state of btn_lr to buttons_state_last buttons_state_last &= ~btn_lr; buttons_state_last |= buttons_state & btn_lr; // check buttons if (btns(btn_l)) { // left if (*mbs == MBS_LEFT) break; // already was left state = MBS_LEFT; *pv = val; // save previous value val = etm->reverse ? etf->max : etf->min; } else if (btns(btn_r)) { // right if (*mbs == MBS_RIGHT) break; // already was right state = MBS_RIGHT; *pv = val; // save previous value val = etm->reverse ? etf->min : etf->max; } else { // center if (*mbs == MBS_RELEASED) break; // already was center state = MBS_RELEASED; if (etm->previous_val) { if (*mbs != MBS_INITIALIZE) val = *pv; } else val = etf->reset; } AVAL(val); if (*mbs == MBS_INITIALIZE) { // show nothing when doing initialize *mbs = state; break; } *mbs = state; btnr(btn_lr); key_beep(); // if another button was pressed, leave this screen if (buttons) break; if (buttons_state != buttons_state_last) break; // show function id first time if (!value_showed) { value_showed = 1; menu_et_function_show_id(etf); } // show current value if (etf->show_func) etf->show_func(etf->name, val); else lcd_char_num3(val); lcd_update(); // sleep 5s, and if no button was changed during, end this screen delay_time = POPUP_DELAY * 200; while (delay_time && !(buttons & ~btn_lr) && (buttons_state == buttons_state_last)) delay_time = delay_menu(delay_time); if ((buttons_state & btn_lr) == (buttons_state_last & btn_lr)) break; } btnr(btn_lr); if (value_showed) lcd_menu(0); // set MENU off return value_showed; } // if button is not initialized, do it if (*mbs == MBS_INITIALIZE) { // set value to default only for non-config values (mixes, channels...) if (etf->flags & EF_NOCONFIG) { val = etf->reset; AVAL(val); } *mbs = MBS_RELEASED; } // return when key was not pressed if (!btn(btn_lr)) return 0; // convert steps step = steps_map[etm->step]; // show MENU and CHANNEL menu_et_function_show_id(etf); while (1) { u8 val_set_to_reset = 0; // check value left/right if (btnl_all(btn_lr)) { // both long keys together key_beep(); if (etf->long_func && etm->buttons == ETB_SPECIAL) // special handling etf->long_func(etf->name, &val, btn_l, btn_r); else { // reset to given reset value val = etf->reset; } AVAL(val); if (val == etf->reset) val_set_to_reset = 1; btnr(btn_lr); } else if (btn(btn_lr)) { if (!btns_all(btn_lr)) { // only one key is currently pressed key_beep(); if (etf->long_func && etm->buttons == ETB_SPECIAL && btnl(btn_lr)) // special handling etf->long_func(etf->name, &val, btn_l, btn_r); else if ((etm->buttons == ETB_LONG_RESET || etm->buttons == ETB_LONG_ENDVAL) && btnl(btn_lr)) { // handle long key press if (etm->buttons == ETB_LONG_RESET) { val = etf->reset; } else { // set side value if ((u8)(btn(btn_l) ? 1 : 0) ^ etm->reverse) val = etf->min; else val = etf->max; } } else { // handle short key press if ((u8)(btn(btn_l) ? 1 : 0) ^ etm->reverse) { val -= step; if (val < etf->min) { if (etm->rotate) val = etf->max; else val = etf->min; } if (etm->opposite_reset && val > etf->reset) val = etf->reset; } else { val += step; if (val > etf->max) { if (etm->rotate) val = etf->min; else val = etf->max; } if (etm->opposite_reset && val < etf->reset) val = etf->reset; } } AVAL(val); if (val == etf->reset) val_set_to_reset = 1; btnr(btn_lr); } else btnr_nolong(btn_lr); // keep long-presses for testing-both } else if (btn(BTN_ROT_ALL)) { s16 val2 = val; val = menu_change_val(val, etf->min, etf->max, etf->rot_fast_step, etm->rotate); // if encoder skipped reset value, set it to reset value if (val2 < etf->reset && val > etf->reset || val2 > etf->reset && val < etf->reset) val = etf->reset; AVAL(val); if (val == etf->reset) val_set_to_reset = 1; } btnr(BTN_ROT_ALL); // longer beep at value reset value if (val_set_to_reset) BEEP_RESET; // if another button was pressed, leave this screen if (buttons) break; if ((buttons_state & ~btn_lr) != buttons_state_last) break; // show current value if (etf->show_func) etf->show_func(etf->name, val); else lcd_char_num3(val); lcd_update(); // if reset value was reached, ignore rotate/btn_lr for some time delay_time = POPUP_DELAY * 200; if (val_set_to_reset) { u8 delay = RESET_VALUE_DELAY; while (delay && !(buttons & ~(btn_lr | BTN_ROT_ALL)) && ((buttons_state & ~btn_lr) == buttons_state_last)) delay = (u8)delay_menu(delay); btnr(BTN_ROT_ALL | btn_lr); delay_time -= RESET_VALUE_DELAY; } // sleep 5s, and if no button was changed during, end this screen while (delay_time && !buttons && ((buttons_state & ~btn_lr) == buttons_state_last)) delay_time = delay_menu(delay_time); if (!buttons) break; // timeouted without button press } btnr(btn_lr); // reset also long values // set MENU off lcd_menu(0); // save model config config_model_save(); return 1; }
int v2_get_parm_c( struct PARBLK *parblock, /* in: parblock to use */ char *name, /* in: name of parm to get */ char *value, /* out: returned value */ int *count, /* out: # of items in parameter */ int *def, /* out: 1 if defaulted, 0 if entered */ int maxcnt, /* in: max # of items to return */ int length, /* in: length of each string in array */ int double_flag /* in: TRUE for double, FALSE for float */ ) { int i; struct VARIABLE *v; /* ptr to VARIABLE struct for this parm */ int *int_ptr; float *float_ptr; double *double_ptr; v = p_fvar(parblock, name); /* p_fvar() ignores case */ if (v == NULL) { *count = 0; v2_error_handler(NO_UNIT, PARAM_NOT_FOUND); return PARAM_NOT_FOUND; } if (maxcnt > 0) *count = MIN(v->v_count, maxcnt); else *count = v->v_count; *def = v->v_default; if (*count <= 0) return SUCCESS; /* null parameter - no need to store */ switch (v->v_type) { /* store value according to type */ case V_INTEGER: int_ptr = (int *)value; for (i = 0; i < *count; i++) *int_ptr++ = IVAL(*v, i); break; case V_REAL: if (double_flag) { /* double precision */ double_ptr = (double *)value; for (i = 0; i < *count; i++) *double_ptr++ = RVAL(*v, i); } else { /* single precision */ float_ptr = (float *)value; for (i = 0; i < *count; i++) *float_ptr++ = RVAL(*v, i); } break; case V_STRING: if (*count == 1) { /* single value, do it the easy way */ if (length == 0) strcpy(value, SVAL(*v,0)); /* no max length */ else { strncpy(value, SVAL(*v,0), length); *(value+length-1) = '\0'; /* make sure of a terminator */ } } else { /* multiple values */ if (length == 0) /* No length, so pack for XVSPTR (grrr) */ v2_pack_xvsptr(value, v, *count); else { /* Normal C 2D array of chars */ for (i = 0; i < *count; i++) { strncpy(value + i*length, SVAL(*v,i), length); *(value + i*length + length-1) = '\0'; /* ensure terminator */ } } } break; default: *count = 0; v2_error_handler(NO_UNIT, PARBLK_ERROR); return PARBLK_ERROR; } return SUCCESS; }
/* Prints a usage message based on contents of optlist. * Parameters: * scanner - The scanner, already initialized with scanopt_init(). * fp - The file stream to write to. * usage - Text to be prepended to option list. * Return: Always returns 0 (zero). * The output looks something like this: [indent][option, alias1, alias2...][indent][description line1 description line2...] */ int scanopt_usage (scanopt_t *scanner, FILE *fp, const char *usage) { struct _scanopt_t *s; int i, columns; const int indent = 2; usg_elem *byr_val = NULL; /* option indices sorted by r_val */ usg_elem *store; /* array of preallocated elements. */ int store_idx = 0; usg_elem *ue; int opt_col_width = 0, desc_col_width = 0; int desccol; int print_run = 0; s = (struct _scanopt_t *) scanner; if (usage) { fprintf (fp, "%s\n", usage); } else { fprintf (fp, _("Usage: %s [OPTIONS]...\n"), s->argv[0]); } fprintf (fp, "\n"); /* Sort by r_val and string. Yes, this is O(n*n), but n is small. */ store = malloc((size_t) s->optc * sizeof (usg_elem)); for (i = 0; i < s->optc; i++) { /* grab the next preallocate node. */ ue = store + store_idx++; ue->idx = i; ue->next = ue->alias = NULL; /* insert into list. */ if (!byr_val) byr_val = ue; else { int found_alias = 0; usg_elem **ue_curr, **ptr_if_no_alias = NULL; ue_curr = &byr_val; while (*ue_curr) { if (RVAL (s, (*ue_curr)->idx) == RVAL (s, ue->idx)) { /* push onto the alias list. */ ue_curr = &((*ue_curr)->alias); found_alias = 1; break; } if (!ptr_if_no_alias && strcasecmp (NAME (s, (*ue_curr)->idx), NAME (s, ue->idx)) > 0) { ptr_if_no_alias = ue_curr; } ue_curr = &((*ue_curr)->next); } if (!found_alias && ptr_if_no_alias) ue_curr = ptr_if_no_alias; ue->next = *ue_curr; *ue_curr = ue; } } #if 0 if (1) { printf ("ORIGINAL:\n"); for (i = 0; i < s->optc; i++) printf ("%2d: %s\n", i, NAME (s, i)); printf ("SORTED:\n"); ue = byr_val; while (ue) { usg_elem *ue2; printf ("%2d: %s\n", ue->idx, NAME (s, ue->idx)); for (ue2 = ue->alias; ue2; ue2 = ue2->next) printf (" +---> %2d: %s\n", ue2->idx, NAME (s, ue2->idx)); ue = ue->next; } } #endif /* Now build each row of output. */ /* first pass calculate how much room we need. */ for (ue = byr_val; ue; ue = ue->next) { usg_elem *ap; int len; len = PRINTLEN(s, ue->idx); for (ap = ue->alias; ap; ap = ap->next) { len += PRINTLEN(s, ap->idx) + (int) strlen(", "); } if (len > opt_col_width) opt_col_width = len; /* It's much easier to calculate length for description column! */ len = (int) strlen (DESC (s, ue->idx)); if (len > desc_col_width) desc_col_width = len; } /* Determine how much room we have, and how much we will allocate to each col. * Do not address pathological cases. Output will just be ugly. */ columns = get_cols () - 1; if (opt_col_width + desc_col_width + indent * 2 > columns) { /* opt col gets whatever it wants. we'll wrap the desc col. */ desc_col_width = columns - (opt_col_width + indent * 2); if (desc_col_width < 14) /* 14 is arbitrary lower limit on desc width. */ desc_col_width = INT_MAX; } desccol = opt_col_width + indent * 2; #define PRINT_SPACES(fp,n) \ fprintf((fp), "%*s", (n), "") /* Second pass (same as above loop), this time we print. */ /* Sloppy hack: We iterate twice. The first time we print short and long options. The second time we print those lines that have ONLY long options. */ while (print_run++ < 2) { for (ue = byr_val; ue; ue = ue->next) { usg_elem *ap; int nwords = 0, nchars = 0, has_short = 0; /* TODO: get has_short schtick to work */ has_short = !(FLAGS (s, ue->idx) & IS_LONG); for (ap = ue->alias; ap; ap = ap->next) { if (!(FLAGS (s, ap->idx) & IS_LONG)) { has_short = 1; break; } } if ((print_run == 1 && !has_short) || (print_run == 2 && has_short)) continue; PRINT_SPACES (fp, indent); nchars += indent; /* Print, adding a ", " between aliases. */ #define PRINT_IT(i) do{\ if(nwords++)\ nchars+=fprintf(fp,", ");\ nchars+=fprintf(fp,"%s",s->options[i].opt_fmt);\ }while(0) if (!(FLAGS (s, ue->idx) & IS_LONG)) PRINT_IT (ue->idx); /* print short aliases first. */ for (ap = ue->alias; ap; ap = ap->next) { if (!(FLAGS (s, ap->idx) & IS_LONG)) PRINT_IT (ap->idx); } if (FLAGS (s, ue->idx) & IS_LONG) PRINT_IT (ue->idx); /* repeat the above loop, this time for long aliases. */ for (ap = ue->alias; ap; ap = ap->next) { if (FLAGS (s, ap->idx) & IS_LONG) PRINT_IT (ap->idx); } /* pad to desccol */ PRINT_SPACES (fp, desccol - nchars); /* Print description, wrapped to desc_col_width columns. */ if (1) { const char *pstart; pstart = DESC (s, ue->idx); while (1) { int n = 0; const char *lastws = NULL, *p; p = pstart; while (*p && n < desc_col_width && *p != '\n') { if (isspace ((unsigned char)(*p)) || *p == '-') lastws = p; n++; p++; } if (!*p) { /* hit end of desc. done. */ fprintf (fp, "%s\n", pstart); break; } else if (*p == '\n') { /* print everything up to here then wrap. */ fprintf (fp, "%.*s\n", n, pstart); PRINT_SPACES (fp, desccol); pstart = p + 1; continue; } else { /* we hit the edge of the screen. wrap at space if possible. */ if (lastws) { fprintf (fp, "%.*s\n", (int)(lastws - pstart), pstart); pstart = lastws + 1; } else { fprintf (fp, "%.*s\n", n, pstart); pstart = p + 1; } PRINT_SPACES (fp, desccol); continue; } } } } } /* end while */ free (store); return 0; }
inline void r_store_stack(CF, R0) { stack_push(RVAL(r0)); }
inline void r_load_local(CF, R0, LOCAL) { RVAL(r0) = call_frame->scope->get_local(local); }
static void resetDevice() { reset_Reset(1,0); RVAL(Status) = 0; setVirtqBase(0); }