static void cmd_units(void) { int units, quantity; unsigned long qmask; unsigned long m; /* mask with bit x set to indicate quantity x specified */ real factor; qmask = get_qlist(0); if (!qmask) return; if (qmask == BIT(Q_DEFAULT)) { default_units(pcs); return; } factor = read_numeric(fTrue, NULL); if (factor == 0.0) { compile_error_skip(-/**UNITS factor must be non-zero*/200); return; } if (factor == HUGE_REAL) factor = (real)1.0; units = get_units(qmask, fTrue); if (units == UNITS_NULL) return; if (TSTBIT(qmask, Q_GRADIENT)) pcs->f_clino_percent = (units == UNITS_PERCENT); if (TSTBIT(qmask, Q_BACKGRADIENT)) pcs->f_backclino_percent = (units == UNITS_PERCENT); factor *= factor_tab[units]; for (quantity = 0, m = BIT(quantity); m <= qmask; quantity++, m <<= 1) if (qmask & m) pcs->units[quantity] = factor; }
static void check_node(prefix *p) { if (!p->pos) { if (!TSTBIT(p->sflags, SFLAGS_SURVEY)) { /* Could do away with the SFLAGS_SURVEY check and check * p->min_export instead of p->max_export I think ... */ if (TSTBIT(p->sflags, SFLAGS_ENTRANCE) || p->max_export) { /* p is a station which was referred to in "*entrance" and/or * "*export" but not elsewhere (otherwise it'd have a position). * p could also be a survey (SFLAGS_SURVEY) or be mentioned as * a station, but only in a line of data which was rejected * because of an error. */ warning_in_file(p->filename, p->line, /*Station “%s” referred to by *entrance or *export but never used*/190, sprint_prefix(p)); } } } else { /* Do we need to worry about export violations in hanging surveys? */ if (fExportUsed) { #if 0 printf("L min %d max %d pfx %s\n", p->min_export, p->max_export, sprint_prefix(p)); #endif if ((p->min_export > 1 && p->min_export != USHRT_MAX) || (p->min_export == 0 && p->max_export)) { char *s; prefix *where = p->up; int msgno; SVX_ASSERT(where); s = osstrdup(sprint_prefix(where)); /* Report better when station called 2.1 for example */ while (!where->filename && where->up) where = where->up; if (TSTBIT(where->sflags, SFLAGS_PREFIX_ENTERED)) { msgno = /*Station “%s” not exported from survey “%s”*/26; } else { /* TRANSLATORS: This error occurs if there's an attempt to * export a station from a survey which doesn't actually exist. */ msgno = /*Reference to station “%s” from non-existent survey “%s”*/286; } compile_error_pfx(where, msgno, sprint_prefix(p), s); osfree(s); } } if (TSTBIT(p->sflags, SFLAGS_SUSPECTTYPO)) { /* TRANSLATORS: Here "station" is a survey station, not a train station. */ warning_in_file(p->filename, p->line, /*Station “%s” referred to just once, with an explicit survey name - typo?*/70, sprint_prefix(p)); } } }
static void check_reentry(prefix *tag) { /* Don't try to check "*prefix \" or "*begin \" */ if (!tag->up) return; if (TSTBIT(tag->sflags, SFLAGS_PREFIX_ENTERED)) { if (tag->line != file.line || strcmp(tag->filename, file.filename) != 0) { const char *filename_store = file.filename; unsigned int line_store = file.line; static int reenter_depr_count = 0; if (reenter_depr_count < 5) { compile_warning(/*Reentering an existing prefix level is deprecated*/29); if (++reenter_depr_count == 5) compile_warning(/*Further uses of this deprecated feature will not be reported*/95); } file.filename = tag->filename; file.line = tag->line; compile_warning(/*Originally entered here*/30); file.filename = filename_store; file.line = line_store; } } else { tag->sflags |= BIT(SFLAGS_PREFIX_ENTERED); tag->filename = file.filename; tag->line = file.line; } }
void kbPutCh() { while ( TSTBIT( p_keyboard->status , KB_GETCH ) ) { ; } if ( TSTBIT( p_keyboard->status , KB_PUTCH ) == 0 ) { SETBIT( p_keyboard->status , KB_PUTCH ); if ( !( TSTBIT( p_keyboard->status , KB_BUFFER_FULL ) ) ) { p_keyboard->Buffer[p_keyboard->BufPos] = getch(); // printf("\n\r kbPutCh: BufPos %d c %02X", p_keyboard->BufPos, p_keyboard->Buffer[p_keyboard->BufPos] ); kbIncBufPos(); } CLRBIT( p_keyboard->status , KB_PUTCH ); } }
static void _mem_send_data( dt_8bit dt ) { gate_set_val( devMemory->mem_gate[ MEM_Data_00 ], (TSTBIT(dt,0)==STATO_VAL_MIN ? STATO_VAL_MIN : STATO_VAL_MAX) ); gate_set_val( devMemory->mem_gate[ MEM_Data_01 ], (TSTBIT(dt,1)==STATO_VAL_MIN ? STATO_VAL_MIN : STATO_VAL_MAX) ); gate_set_val( devMemory->mem_gate[ MEM_Data_02 ], (TSTBIT(dt,2)==STATO_VAL_MIN ? STATO_VAL_MIN : STATO_VAL_MAX) ); gate_set_val( devMemory->mem_gate[ MEM_Data_03 ], (TSTBIT(dt,3)==STATO_VAL_MIN ? STATO_VAL_MIN : STATO_VAL_MAX) ); gate_set_val( devMemory->mem_gate[ MEM_Data_04 ], (TSTBIT(dt,4)==STATO_VAL_MIN ? STATO_VAL_MIN : STATO_VAL_MAX) ); gate_set_val( devMemory->mem_gate[ MEM_Data_05 ], (TSTBIT(dt,5)==STATO_VAL_MIN ? STATO_VAL_MIN : STATO_VAL_MAX) ); gate_set_val( devMemory->mem_gate[ MEM_Data_06 ], (TSTBIT(dt,6)==STATO_VAL_MIN ? STATO_VAL_MIN : STATO_VAL_MAX) ); gate_set_val( devMemory->mem_gate[ MEM_Data_07 ], (TSTBIT(dt,7)==STATO_VAL_MIN ? STATO_VAL_MIN : STATO_VAL_MAX) ); }
void default_units(settings *s) { int quantity; for (quantity = 0; quantity < Q_MAC; quantity++) { if (TSTBIT(ANG_QMASK, quantity)) s->units[quantity] = (real)(M_PI / 180.0); /* degrees */ else s->units[quantity] = (real)1.0; /* metres */ } s->f_clino_percent = s->f_backclino_percent = fFalse; }
uchar kbGetCh() { uchar c = '\0'; uchar i; while ( TSTBIT( p_keyboard->status , KB_PUTCH ) ) { ; } SETBIT( p_keyboard->status , KB_GETCH ); if ( !( TSTBIT( p_keyboard->status , KB_BUFFER_EMPTY ) ) ) { c = p_keyboard->Buffer[ KB_BUFFER_MIN_POS ]; for ( i=KB_BUFFER_MIN_POS ; i < p_keyboard->BufPos ; i++ ) { p_keyboard->Buffer[ i ] = p_keyboard->Buffer[ i + 1 ]; // printf("\n\r kbGetCh: i %d BufPos %d c %02X", i, p_keyboard->BufPos, p_keyboard->Buffer[i] ); } p_keyboard->Buffer[ p_keyboard->BufPos ] = '\0'; kbDecBufPos(); } CLRBIT( p_keyboard->status , KB_GETCH ); return c; }
static int get_units(unsigned long qmask, bool percent_ok) { static sztok utab[] = { {"DEGREES", UNITS_DEGS }, {"DEGS", UNITS_DEGS }, {"FEET", UNITS_FEET }, {"GRADS", UNITS_GRADS }, {"METERS", UNITS_METRES }, {"METRES", UNITS_METRES }, {"METRIC", UNITS_METRES }, {"MILS", UNITS_GRADS }, {"MINUTES", UNITS_MINUTES }, {"PERCENT", UNITS_PERCENT }, {"PERCENTAGE", UNITS_PERCENT }, {"YARDS", UNITS_YARDS }, {NULL, UNITS_NULL } }; int units; get_token(); units = match_tok(utab, TABSIZE(utab)); if (units == UNITS_NULL) { file.lpos += strlen(buffer); compile_error_skip(-/*Unknown units “%s”*/35, buffer); return UNITS_NULL; } if (units == UNITS_PERCENT && percent_ok && !(qmask & ~(BIT(Q_GRADIENT)|BIT(Q_BACKGRADIENT)))) { return units; } if (((qmask & LEN_QMASK) && !TSTBIT(LEN_UMASK, units)) || ((qmask & ANG_QMASK) && !TSTBIT(ANG_UMASK, units))) { file.lpos += strlen(buffer); compile_error_skip(-/*Invalid units “%s” for quantity*/37, buffer); return UNITS_NULL; } return units; }
/*----------------------------------------------------------------------*/ static int omatch( const tchar * * strp, const pattern * pat, const tchar * start ) { /* * Match one pattern element, pointed at by pat, against the character at * **strp. Return 0 on a failure, 1 on success. *strp is advanced to skip * over the matched character on a successful match. Closure is handled one * level up by patcmp(). * * "start" points at the character at the left edge of the line. This might * not be the same thing as *strp if the search is starting in the middle * of the string. An end-of- line anchor matches '\n' or '\0'. */ int advance = -1; /* amount to advance *strp, -1 == error */ switch (*pat) { case M_BOL: /* First char in string? */ if (*strp == start) /* Only one star here. */ advance = 0; break; case M_ANY: /* . = anything but newline */ if (**strp != _T('\n')) advance = 1; break; case M_EOL: if (**strp == _T('\n') || **strp == _T('\0')) advance = 0; break; case M_CCL: if (TSTBIT(**strp, pat + 1)) advance = 1; break; default: /* literal match */ if (**strp == *pat) advance = 1; break; } if (advance > 0) *strp += advance; return (advance + 1); }
void busShow( t_window* dsp ) { p_wlist r; p_slist c; dsp->cursor.y = dsp->start.y; for ( r = p_all_wires; r != NULL; r=r->w_next ) { if ( r->Wire->visible == W_VISIBLE ) { dsp->cursor.x = dsp->start.x; mvwprintw( dsp->wnd, dsp->cursor.y , dsp->cursor.x, "%s: ", r->Wire->nome ); dsp->cursor.x += 9; for ( c = r->Wire->stato->oldest ; c != NULL; c = c->s_next ) { if ( TSTBIT( c->flag, STATO_FLAG_LOW ) ) mvwprintw( dsp->wnd, dsp->cursor.y , dsp->cursor.x, "_" ); if ( TSTBIT( c->flag, STATO_FLAG_HIGH ) ) mvwprintw( dsp->wnd, dsp->cursor.y , dsp->cursor.x, "'" ); if ( TSTBIT( c->flag, STATO_FLAG_RAISE ) ) mvwprintw( dsp->wnd, dsp->cursor.y , dsp->cursor.x, "/" ); if ( TSTBIT( c->flag, STATO_FLAG_FALL ) ) mvwprintw( dsp->wnd, dsp->cursor.y , dsp->cursor.x, "\\" ); //mvwprintw( dsp->wnd, dsp->cursor.y , dsp->cursor.x, "%d", c->valore ); dsp->cursor.x += 1; } dsp->cursor.y++; } } wrefresh( dsp->wnd ); }
static void cmd_calibrate(void) { real sc, z; unsigned long qmask, m; int quantity; qmask = get_qlist(BIT(Q_POS)|BIT(Q_PLUMB)|BIT(Q_LEVEL)); if (!qmask) return; /* error already reported */ if (qmask == BIT(Q_DEFAULT)) { default_calib(pcs); return; } if (((qmask & LEN_QMASK)) && ((qmask & ANG_QMASK))) { compile_error_skip(/*Can’t calibrate angular and length quantities together*/227); return; } z = read_numeric(fFalse, NULL); sc = read_numeric(fTrue, NULL); if (sc == HUGE_REAL) sc = (real)1.0; /* check for declination scale */ /* perhaps "*calibrate declination XXX" should be "*declination XXX" ? */ if (TSTBIT(qmask, Q_DECLINATION) && sc != 1.0) { compile_error_skip(-/*Scale factor must be 1.0 for DECLINATION*/40); return; } if (sc == 0.0) { compile_error_skip(-/*Scale factor must be non-zero*/391); return; } for (quantity = 0, m = BIT(quantity); m <= qmask; quantity++, m <<= 1) { if (qmask & m) { pcs->z[quantity] = pcs->units[quantity] * z; pcs->sc[quantity] = sc; } } }
static prefix * new_anon_station(void) { prefix *name = osnew(prefix); name->pos = NULL; name->ident = NULL; name->shape = 0; name->stn = NULL; name->up = pcs->Prefix; name->down = NULL; name->filename = file.filename; name->line = file.line; if (TSTBIT(pcs->infer, INFER_EXPORTS)) { name->min_export = USHRT_MAX; } else { name->min_export = 0; } name->max_export = 0; name->sflags = BIT(SFLAGS_ANON); /* Keep linked list of anon stations for node stats. */ name->right = anon_list; anon_list = name; return name; }
extern void articulate(void) { node *stn, *stnStart; int i; long cFixed; component_list = NULL; articulation_list = NULL; artlist = NULL; fixedlist = NULL; /* find articulation points and components */ colour = 0; stnStart = NULL; cMaxVisits = 0; FOR_EACH_STN(stn, stnlist) { if (fixed(stn)) { remove_stn_from_list(&stnlist, stn); add_stn_to_list(&fixedlist, stn); colour++; stn->colour = -colour; #ifdef DEBUG_ARTIC printf("Putting stn "); print_prefix(stn->name); printf(" on fixedlist\n"); #endif } else { cMaxVisits++; stn->colour = 0; } } dirn_stack = osmalloc(cMaxVisits); min_stack = osmalloc(cMaxVisits * sizeof(long)); /* fixedlist can be NULL here if we've had a *solve followed by survey * which is all hanging. */ cFixed = colour; while (fixedlist) { int c; stnStart = fixedlist; stn = stnStart; /* see if this is a fresh component - it may not be, we may be * processing the other way from a fixed point cut-line */ if (stn->colour < 0) { #ifdef DEBUG_ARTIC printf("new component\n"); #endif stn->colour = -stn->colour; /* fixed points are negative until we colour from them */ cComponents++; /* FIXME: logic to count components isn't the same as the logic * to start a new one - we should start a new one for a fixed point * cut-line (see below) */ if (artlist) { component *comp; articulation *art; art = osnew(articulation); art->stnlist = artlist; art->next = articulation_list; articulation_list = art; artlist = NULL; comp = osnew(component); comp->next = component_list; comp->artic = articulation_list; component_list = comp; articulation_list = NULL; } #ifdef DEBUG_ARTIC print_prefix(stn->name); printf(" [%p] is root of component %ld\n", stn, cComponents); printf(" and colour = %d/%d\n", stn->colour, cFixed); #endif } c = 0; for (i = 0; i <= 2 && stn->leg[i]; i++) { node *stn2 = stn->leg[i]->l.to; if (stn2->colour < 0) { stn2->colour = -stn2->colour; } else if (stn2->colour == 0) { /* Special case to check if start station is an articulation point * which it is iff we have to colour from it in more than one dirn * * We're looking for articulation legs - these are those where * colouring from here doesn't reach a fixed point (including * stn - the fixed point we've started from) * * FIXME: this is a "fixed point cut-line" case where we could * start a new component. */ long col = visit(stn2, reverse_leg_dirn(stn->leg[i])); #ifdef DEBUG_ARTIC print_prefix(stn->name); printf(" -> "); print_prefix(stn2->name); printf(" col %d cFixed %d\n", col, cFixed); #endif if (col > cFixed) { /* start new articulation - FIXME - overeager */ articulation *art = osnew(articulation); art->stnlist = artlist; art->next = articulation_list; articulation_list = art; artlist = NULL; c |= 1 << i; } } } switch (c) { /* had to colour in 2 or 3 directions from start point */ case 3: case 5: case 6: case 7: #ifdef DEBUG_ARTIC print_prefix(stn->name); printf(" is a special case start articulation point [%d]\n", c); #endif for (i = 0; i <= 2 && stn->leg[i]; i++) { if (TSTBIT(c, i)) { /* flag leg as an articulation for loop error reporting */ stn->leg[i]->l.reverse |= FLAG_ARTICULATION; #ifdef DEBUG_ARTIC print_prefix(stn->leg[i]->l.to->name); putnl(); #endif reverse_leg(stn->leg[i])->l.reverse |= FLAG_ARTICULATION; } } } #ifdef DEBUG_ARTIC printf("Putting FIXED stn "); print_prefix(stn->name); printf(" on artlist\n"); #endif remove_stn_from_list(&fixedlist, stn); add_stn_to_list(&artlist, stn); if (stnStart->colour == 1) { #ifdef DEBUG_ARTIC printf("%ld components\n",cComponents); #endif break; } } osfree(dirn_stack); dirn_stack = NULL; osfree(min_stack); min_stack = NULL; if (artlist) { articulation *art = osnew(articulation); art->stnlist = artlist; art->next = articulation_list; articulation_list = art; artlist = NULL; } if (articulation_list) { component *comp = osnew(component); comp->next = component_list; comp->artic = articulation_list; component_list = comp; articulation_list = NULL; } if (stnlist) { /* Any stations still in stnlist are unfixed, which is means we have * one or more hanging surveys. * * The cause of the problem is pretty likely to be a typo, so run the * checks which report errors and warnings about issues which such a * typo is likely to result in. */ check_node_stats(); /* Actually this error is fatal, but we want to list the survey * stations which aren't connected, so we report it as an error * and die after listing them... */ bool fNotAttached = fFalse; error(/*Survey not all connected to fixed stations*/45); FOR_EACH_STN(stn, stnlist) { /* Anonymous stations must be at the end of a trailing traverse (since * the same anonymous station can't be referred to more than once), * and trailing traverses have been removed at this point. */ SVX_ASSERT(!TSTBIT(stn->name->sflags, SFLAGS_ANON)); if (stn->name->ident) { if (!fNotAttached) { fNotAttached = fTrue; puts(msg(/*The following survey stations are not attached to a fixed point:*/71)); } puts(sprint_prefix(stn->name)); } } exit(EXIT_FAILURE); }
static void cmd_data(void) { static sztok dtab[] = { {"ALTITUDE", Dz }, {"BACKBEARING", BackComp }, {"BACKCLINO", BackClino }, /* alternative name */ {"BACKCOMPASS", BackComp }, /* alternative name */ {"BACKGRADIENT", BackClino }, {"BEARING", Comp }, {"CEILING", Up }, /* alternative name */ {"CLINO", Clino }, /* alternative name */ {"COMPASS", Comp }, /* alternative name */ {"COUNT", Count }, /* FrCount&ToCount in multiline */ {"DEPTH", Depth }, /* FrDepth&ToDepth in multiline */ {"DEPTHCHANGE", DepthChange }, {"DIRECTION", Dir }, {"DOWN", Down }, {"DX", Dx }, {"DY", Dy }, {"DZ", Dz }, {"EASTING", Dx }, {"FLOOR", Down }, /* alternative name */ {"FROM", Fr }, {"FROMCOUNT", FrCount }, {"FROMDEPTH", FrDepth }, {"GRADIENT", Clino }, {"IGNORE", Ignore }, {"IGNOREALL", IgnoreAll }, {"LEFT", Left }, {"LENGTH", Tape }, {"NEWLINE", Newline }, {"NORTHING", Dy }, {"RIGHT", Right }, {"STATION", Station }, /* Fr&To in multiline */ {"TAPE", Tape }, /* alternative name */ {"TO", To }, {"TOCOUNT", ToCount }, {"TODEPTH", ToDepth }, {"UP", Up }, {NULL, End } }; #define MASK_stns BIT(Fr) | BIT(To) | BIT(Station) #define MASK_tape BIT(Tape) | BIT(FrCount) | BIT(ToCount) | BIT(Count) #define MASK_dpth BIT(FrDepth) | BIT(ToDepth) | BIT(Depth) | BIT(DepthChange) #define MASK_comp BIT(Comp) | BIT(BackComp) #define MASK_clin BIT(Clino) | BIT(BackClino) #define MASK_NORMAL MASK_stns | BIT(Dir) | MASK_tape | MASK_comp | MASK_clin #define MASK_DIVING MASK_stns | BIT(Dir) | MASK_tape | MASK_comp | MASK_dpth #define MASK_CARTESIAN MASK_stns | BIT(Dx) | BIT(Dy) | BIT(Dz) #define MASK_CYLPOLAR MASK_stns | BIT(Dir) | MASK_tape | MASK_comp | MASK_dpth #define MASK_PASSAGE BIT(Station) | BIT(Left) | BIT(Right) | BIT(Up) | BIT(Down) #define MASK_NOSURVEY MASK_stns /* readings which may be given for each style */ static const unsigned long mask[] = { MASK_NORMAL, MASK_DIVING, MASK_CARTESIAN, MASK_CYLPOLAR, MASK_NOSURVEY, MASK_PASSAGE }; /* readings which may be omitted for each style */ static const unsigned long mask_optional[] = { BIT(Dir) | BIT(Clino) | BIT(BackClino), BIT(Dir), 0, BIT(Dir), 0, 0 /* BIT(Left) | BIT(Right) | BIT(Up) | BIT(Down), */ }; /* all valid readings */ static const unsigned long mask_all[] = { MASK_NORMAL | BIT(Newline) | BIT(Ignore) | BIT(IgnoreAll) | BIT(End), MASK_DIVING | BIT(Newline) | BIT(Ignore) | BIT(IgnoreAll) | BIT(End), MASK_CARTESIAN | BIT(Newline) | BIT(Ignore) | BIT(IgnoreAll) | BIT(End), MASK_CYLPOLAR | BIT(Newline) | BIT(Ignore) | BIT(IgnoreAll) | BIT(End), MASK_NOSURVEY | BIT(Ignore) | BIT(IgnoreAll) | BIT(End), MASK_PASSAGE | BIT(Ignore) | BIT(IgnoreAll) | BIT(End) }; #define STYLE_DEFAULT -2 #define STYLE_UNKNOWN -1 static sztok styletab[] = { {"CARTESIAN", STYLE_CARTESIAN }, {"CYLPOLAR", STYLE_CYLPOLAR }, {"DEFAULT", STYLE_DEFAULT }, {"DIVING", STYLE_DIVING }, {"NORMAL", STYLE_NORMAL }, {"NOSURVEY", STYLE_NOSURVEY }, {"PASSAGE", STYLE_PASSAGE }, {"TOPOFIL", STYLE_NORMAL }, {NULL, STYLE_UNKNOWN } }; #define m_multi (BIT(Station) | BIT(Count) | BIT(Depth)) int style, k = 0, kMac; reading *new_order, d; unsigned long mUsed = 0; char *style_name; /* after a bad *data command ignore survey data until the next * *data command to avoid an avalanche of errors */ pcs->style = STYLE_IGNORE; kMac = 6; /* minimum for NORMAL style */ new_order = osmalloc(kMac * sizeof(reading)); get_token(); style = match_tok(styletab, TABSIZE(styletab)); if (style == STYLE_DEFAULT) { default_style(pcs); return; } if (style == STYLE_UNKNOWN) { file.lpos += strlen(buffer); compile_error_skip(-/*Data style “%s” unknown*/65, buffer); return; } skipblanks(); #ifndef NO_DEPRECATED /* Olde syntax had optional field for survey grade, so allow an omit * but issue a warning about it */ if (isOmit(ch)) { static int data_depr_count = 0; if (data_depr_count < 5) { file.lpos += strlen(buffer); compile_warning(-/*“*data %s %c …” is deprecated - use “*data %s …” instead*/104, buffer, ch, buffer); if (++data_depr_count == 5) compile_warning(/*Further uses of this deprecated feature will not be reported*/95); } nextch(); } #endif style_name = osstrdup(buffer); do { filepos fp; get_pos(&fp); get_token(); d = match_tok(dtab, TABSIZE(dtab)); /* only token allowed after IGNOREALL is NEWLINE */ if (k && new_order[k - 1] == IgnoreAll && d != Newline) { set_pos(&fp); break; } /* Note: an unknown token is reported as trailing garbage */ if (!TSTBIT(mask_all[style], d)) { file.lpos += strlen(buffer); compile_error_skip(-/*Reading “%s” not allowed in data style “%s”*/63, buffer, style_name); osfree(style_name); osfree(new_order); return; } if (TSTBIT(mUsed, Newline) && TSTBIT(m_multi, d)) { /* e.g. "*data diving station newline tape depth compass" */ file.lpos += strlen(buffer); compile_error_skip(-/*Reading “%s” must occur before NEWLINE*/225, buffer); osfree(style_name); osfree(new_order); return; } /* Check for duplicates unless it's a special reading: * IGNOREALL,IGNORE (duplicates allowed) ; END (not possible) */ if (!((BIT(Ignore) | BIT(End) | BIT(IgnoreAll)) & BIT(d))) { if (TSTBIT(mUsed, d)) { file.lpos += strlen(buffer); compile_error_skip(-/*Duplicate reading “%s”*/67, buffer); osfree(style_name); osfree(new_order); return; } else { /* Check for previously listed readings which are incompatible * with this one - e.g. Count vs FrCount */ bool fBad = fFalse; switch (d) { case Station: if (mUsed & (BIT(Fr) | BIT(To))) fBad = fTrue; break; case Fr: case To: if (TSTBIT(mUsed, Station)) fBad = fTrue; break; case Count: if (mUsed & (BIT(FrCount) | BIT(ToCount) | BIT(Tape))) fBad = fTrue; break; case FrCount: case ToCount: if (mUsed & (BIT(Count) | BIT(Tape))) fBad = fTrue; break; case Depth: if (mUsed & (BIT(FrDepth) | BIT(ToDepth) | BIT(DepthChange))) fBad = fTrue; break; case FrDepth: case ToDepth: if (mUsed & (BIT(Depth) | BIT(DepthChange))) fBad = fTrue; break; case DepthChange: if (mUsed & (BIT(FrDepth) | BIT(ToDepth) | BIT(Depth))) fBad = fTrue; break; case Newline: if (mUsed & ~m_multi) { /* e.g. "*data normal from to tape newline compass clino" */ file.lpos += strlen(buffer); compile_error_skip(-/*NEWLINE can only be preceded by STATION, DEPTH, and COUNT*/226); osfree(style_name); osfree(new_order); return; } if (k == 0) { file.lpos += strlen(buffer); compile_error_skip(-/*NEWLINE can’t be the first reading*/222); osfree(style_name); osfree(new_order); return; } break; default: /* avoid compiler warnings about unhandled enums */ break; } if (fBad) { /* Not entirely happy with phrasing this... */ file.lpos += strlen(buffer); compile_error_skip(-/*Reading “%s” duplicates previous reading(s)*/77, buffer); osfree(style_name); osfree(new_order); return; } mUsed |= BIT(d); /* used to catch duplicates */ } } if (k && new_order[k - 1] == IgnoreAll) { SVX_ASSERT(d == Newline); k--; d = IgnoreAllAndNewLine; } if (k >= kMac) { kMac = kMac * 2; new_order = osrealloc(new_order, kMac * sizeof(reading)); } new_order[k++] = d; } while (d != End); if (k >= 2 && new_order[k - 2] == Newline) { file.lpos += strlen(buffer); compile_error_skip(-/*NEWLINE can’t be the last reading*/223); osfree(style_name); osfree(new_order); return; } if (style == STYLE_NOSURVEY) { if (TSTBIT(mUsed, Station)) { if (k >= kMac) { kMac = kMac * 2; new_order = osrealloc(new_order, kMac * sizeof(reading)); } new_order[k - 1] = Newline; new_order[k++] = End; } } else if (style == STYLE_PASSAGE) { /* Station doesn't mean "multiline" for STYLE_PASSAGE. */ } else if (!TSTBIT(mUsed, Newline) && (m_multi & mUsed)) { /* This is for when they write * *data normal station tape compass clino * (i.e. no newline, but interleaved readings) */ compile_error_skip(/*Interleaved readings, but no NEWLINE*/224); osfree(style_name); osfree(new_order); return; } #if 0 printf("mUsed = 0x%x\n", mUsed); #endif /* Check the supplied readings form a sufficient set. */ if (style != STYLE_PASSAGE) { if (mUsed & (BIT(Fr) | BIT(To))) mUsed |= BIT(Station); else if (TSTBIT(mUsed, Station)) mUsed |= BIT(Fr) | BIT(To); } if (mUsed & (BIT(Comp) | BIT(BackComp))) mUsed |= BIT(Comp) | BIT(BackComp); if (mUsed & (BIT(Clino) | BIT(BackClino))) mUsed |= BIT(Clino) | BIT(BackClino); if (mUsed & (BIT(FrDepth) | BIT(ToDepth))) mUsed |= BIT(Depth) | BIT(DepthChange); else if (TSTBIT(mUsed, Depth)) mUsed |= BIT(FrDepth) | BIT(ToDepth) | BIT(DepthChange); else if (TSTBIT(mUsed, DepthChange)) mUsed |= BIT(FrDepth) | BIT(ToDepth) | BIT(Depth); if (mUsed & (BIT(FrCount) | BIT(ToCount))) mUsed |= BIT(Count) | BIT(Tape); else if (TSTBIT(mUsed, Count)) mUsed |= BIT(FrCount) | BIT(ToCount) | BIT(Tape); else if (TSTBIT(mUsed, Tape)) mUsed |= BIT(FrCount) | BIT(ToCount) | BIT(Count); #if 0 printf("mUsed = 0x%x, opt = 0x%x, mask = 0x%x\n", mUsed, mask_optional[style], mask[style]); #endif if (((mUsed &~ BIT(Newline)) | mask_optional[style]) != mask[style]) { /* Test should only fail with too few bits set, not too many */ SVX_ASSERT((((mUsed &~ BIT(Newline)) | mask_optional[style]) &~ mask[style]) == 0); compile_error_skip(/*Too few readings for data style “%s”*/64, style_name); osfree(style_name); osfree(new_order); return; } /* don't free default ordering or ordering used by parent */ if (pcs->ordering != default_order && !(pcs->next && pcs->next->ordering == pcs->ordering)) osfree(pcs->ordering); pcs->style = style; pcs->ordering = new_order; osfree(style_name); if (style == STYLE_PASSAGE) { lrudlist * new_psg = osnew(lrudlist); new_psg->tube = NULL; new_psg->next = model; model = new_psg; next_lrud = &(new_psg->tube); } }
static void cmd_fix(void) { prefix *fix_name; node *stn = NULL; static node *stnOmitAlready = NULL; real x, y, z; int nx, ny, nz; filepos fp; fix_name = read_prefix(PFX_STATION|PFX_ALLOW_ROOT); fix_name->sflags |= BIT(SFLAGS_FIXED); get_pos(&fp); get_token(); if (strcmp(ucbuffer, "REFERENCE") == 0) { /* suppress "unused fixed point" warnings for this station */ fix_name->sflags |= BIT(SFLAGS_USED); } else { if (*ucbuffer) set_pos(&fp); } x = read_numeric(fTrue, &nx); if (x == HUGE_REAL) { /* If the end of the line isn't blank, read a number after all to * get a more helpful error message */ if (!isEol(ch) && !isComm(ch)) x = read_numeric(fFalse, &nx); } if (x == HUGE_REAL) { if (stnOmitAlready) { if (fix_name != stnOmitAlready->name) { compile_error_skip(/*More than one FIX command with no coordinates*/56); } else { compile_warning(/*Same station fixed twice with no coordinates*/61); } return; } stn = StnFromPfx(fix_name); compile_warning(/*FIX command with no coordinates - fixing at (0,0,0)*/54); x = y = z = (real)0.0; stnOmitAlready = stn; } else { real sdx; y = read_numeric(fFalse, &ny); z = read_numeric(fFalse, &nz); sdx = read_numeric(fTrue, NULL); if (sdx != HUGE_REAL) { real sdy, sdz; real cxy = 0, cyz = 0, czx = 0; sdy = read_numeric(fTrue, NULL); if (sdy == HUGE_REAL) { /* only one variance given */ sdy = sdz = sdx; } else { sdz = read_numeric(fTrue, NULL); if (sdz == HUGE_REAL) { /* two variances given - horizontal & vertical */ sdz = sdy; sdy = sdx; } else { cxy = read_numeric(fTrue, NULL); if (cxy != HUGE_REAL) { /* covariances given */ cyz = read_numeric(fFalse, NULL); czx = read_numeric(fFalse, NULL); } else { cxy = 0; } } } stn = StnFromPfx(fix_name); if (!fixed(stn)) { node *fixpt = osnew(node); prefix *name; name = osnew(prefix); name->pos = osnew(pos); name->ident = NULL; name->shape = 0; fixpt->name = name; name->stn = fixpt; name->up = NULL; if (TSTBIT(pcs->infer, INFER_EXPORTS)) { name->min_export = USHRT_MAX; } else { name->min_export = 0; } name->max_export = 0; name->sflags = 0; add_stn_to_list(&stnlist, fixpt); POS(fixpt, 0) = x; POS(fixpt, 1) = y; POS(fixpt, 2) = z; fix(fixpt); fixpt->leg[0] = fixpt->leg[1] = fixpt->leg[2] = NULL; addfakeleg(fixpt, stn, 0, 0, 0, sdx * sdx, sdy * sdy, sdz * sdz #ifndef NO_COVARIANCES , cxy, cyz, czx #endif ); } return; } stn = StnFromPfx(fix_name); } if (!fixed(stn)) { POS(stn, 0) = x; POS(stn, 1) = y; POS(stn, 2) = z; fix(stn); return; } if (x != POS(stn, 0) || y != POS(stn, 1) || z != POS(stn, 2)) { compile_error(/*Station already fixed or equated to a fixed point*/46); return; } compile_warning(/*Station already fixed at the same coordinates*/55); }
void *MemoryTask() { p_gate pCE1 = NULL; p_gate pCE2 = NULL; p_gate pRD = NULL; p_gate pWR = NULL; p_slist pSCE1 = NULL; p_slist pSCE2 = NULL; p_slist pSRD = NULL; p_slist pSWR = NULL; dt_16bit ma = 0; dt_8bit dt = 0; pCE1 = devMemory->mem_gate[ MEM__CE1 ]; pCE2 = devMemory->mem_gate[ MEM__CE2 ]; pRD = devMemory->mem_gate[ MEM__RD ]; pWR = devMemory->mem_gate[ MEM__WR ]; if ( pCE1->Wire != NULL ) pSCE1 = pCE1->Wire->stato->att; if ( pCE2->Wire != NULL ) pSCE2 = pCE2->Wire->stato->att; if ( pRD->Wire != NULL ) pSRD = pRD->Wire->stato->att; if ( pWR->Wire != NULL ) pSWR = pWR->Wire->stato->att; // Lettura if ( pSCE1 != NULL && pSRD != NULL ) { if ( (TSTBIT( pSCE1->flag , STATO_FLAG_FALL ) || TSTBIT( pSCE1->flag , STATO_FLAG_LOW )) && TSTBIT( pSRD->flag , STATO_FLAG_FALL ) ) { ma = _mem_read_address(); dt = devMemory->memory[ ma ]; gate_set_state( devMemory->mem_gate[ MEM_Data_00 ], GATEMODE_OUTPUT ); gate_set_state( devMemory->mem_gate[ MEM_Data_01 ], GATEMODE_OUTPUT ); gate_set_state( devMemory->mem_gate[ MEM_Data_02 ], GATEMODE_OUTPUT ); gate_set_state( devMemory->mem_gate[ MEM_Data_03 ], GATEMODE_OUTPUT ); gate_set_state( devMemory->mem_gate[ MEM_Data_04 ], GATEMODE_OUTPUT ); gate_set_state( devMemory->mem_gate[ MEM_Data_05 ], GATEMODE_OUTPUT ); gate_set_state( devMemory->mem_gate[ MEM_Data_06 ], GATEMODE_OUTPUT ); gate_set_state( devMemory->mem_gate[ MEM_Data_07 ], GATEMODE_OUTPUT ); _mem_send_data( dt ); } if ( ( gate_get_state( devMemory->mem_gate[ MEM_Data_00 ] ) == GATEMODE_OUTPUT ) && ( TSTBIT( pSCE1->flag , STATO_FLAG_HIGH ) || TSTBIT( pSCE2->flag , STATO_FLAG_HIGH ) ) ) { gate_set_state( devMemory->mem_gate[ MEM_Data_00 ], GATEMODE_INPUT ); gate_set_state( devMemory->mem_gate[ MEM_Data_01 ], GATEMODE_INPUT ); gate_set_state( devMemory->mem_gate[ MEM_Data_02 ], GATEMODE_INPUT ); gate_set_state( devMemory->mem_gate[ MEM_Data_03 ], GATEMODE_INPUT ); gate_set_state( devMemory->mem_gate[ MEM_Data_04 ], GATEMODE_INPUT ); gate_set_state( devMemory->mem_gate[ MEM_Data_05 ], GATEMODE_INPUT ); gate_set_state( devMemory->mem_gate[ MEM_Data_06 ], GATEMODE_INPUT ); gate_set_state( devMemory->mem_gate[ MEM_Data_07 ], GATEMODE_INPUT ); } } // Scrittura if ( pSCE1 != NULL && pSWR != NULL ) { if ( (TSTBIT( pSCE1->flag , STATO_FLAG_FALL ) || TSTBIT( pSCE1->flag , STATO_FLAG_LOW )) && TSTBIT( pSWR->flag , STATO_FLAG_FALL ) ) { ma = _mem_read_address(); dt = _mem_read_data(); devMemory->memory[ ma ] = dt; } } return NULL; }
void scrWrite( unsigned char c ) { unsigned char d,e; switch ( c ) { case 8: scrBackSpace(); break; case 127: scrBackSpace(); break; case 10: scrReturn(); scrRepaint(); break; case 13: break; case 27: #ifdef _KEYBOARD #ifndef THREAD_KEYBOARD kbPutCh(); #endif switch ( kbGetCh() ) { #else d = getch(); switch ( d ) { #endif case 91: #ifdef _KEYBOARD #ifndef THREAD_KEYBOARD kbPutCh(); #endif switch ( kbGetCh() ) { #else e = getch(); switch ( e ) { #endif case 65: // KEY_UP scrDecY(); break; case 66: // KEY_DOWN scrIncY(); break; case 67: // KEY_RIGHT scrIncX(); break; case 68: // KEY_LEFT scrDecX(); break; default: break; } break; default: break; } break; default: if ( p_screen->x_pos < SCR_XMAX_SIZE ) { p_screen->Buffer[ p_screen->y_pos*SCR_XMAX_SIZE + p_screen->x_pos ] = c; scrIncX(); } } SETBIT(p_screen->status,f_srcContentChanged); } unsigned char scrRead() { return ( p_screen->Buffer[ p_screen->y_pos*SCR_XMAX_SIZE + p_screen->x_pos ] ); } //---------------------------------------------------- void scrRepaint() { curscoord x, y, xs, xe, ys, ye; if ( TSTBIT(p_screen->status,f_srcRepainting) ) return; SETBIT(p_screen->status,f_srcRepainting); if ( TSTBIT(p_screen->status,f_srcContentChanged) ) { x = ( p_screen->x_pos<SCR_POSX_MAX ? p_screen->x_pos : SCR_POSX_MAX ); y = ( p_screen->y_pos<SCR_POSY_MAX ? p_screen->y_pos : SCR_POSY_MAX ); xs = ( x < dspXmax( p_display ) ? 0 : x - dspXmax( p_display ) + 1 ); xe = xs + dspXmax( p_display ) - 1; ys = ( y < dspYmax( p_display ) ? 0 : y - dspYmax( p_display ) + 1 ); ye = ys + dspYmax( p_display ) - 1; dspCursorHome( p_display ); for ( y = ys; y <= ye; y++ ) { for ( x = xs; x <= xe; x++ ) { if ( x-xs < SCR_XMAX_SIZE && y-ys < SCR_YMAX_SIZE ) { dspWrite( p_display, p_screen->Buffer[ y*SCR_XMAX_SIZE + x ] ); } else { dspWrite( p_display, '~' ); } } } #ifndef THREAD_DISPLAY_REPAINT dspRefresh( p_display ); #endif CLRBIT(p_screen->status,f_srcContentChanged); } CLRBIT(p_screen->status,f_srcRepainting); }
/* if prefix is omitted: if PFX_OPT set return NULL, otherwise use longjmp */ extern prefix * read_prefix(unsigned pfx_flags) { bool f_optional = !!(pfx_flags & PFX_OPT); bool fSurvey = !!(pfx_flags & PFX_SURVEY); bool fSuspectTypo = !!(pfx_flags & PFX_SUSPECT_TYPO); prefix *back_ptr, *ptr; char *name; size_t name_len = 32; size_t i; bool fNew; bool fImplicitPrefix = fTrue; int depth = -1; filepos fp_firstsep; skipblanks(); #ifndef NO_DEPRECATED if (isRoot(ch)) { if (!(pfx_flags & PFX_ALLOW_ROOT)) { compile_diagnostic(DIAG_ERR|DIAG_COL, /*ROOT is deprecated*/25); LONGJMP(file.jbSkipLine); } if (root_depr_count < 5) { compile_diagnostic(DIAG_WARN|DIAG_COL, /*ROOT is deprecated*/25); if (++root_depr_count == 5) compile_diagnostic(DIAG_WARN, /*Further uses of this deprecated feature will not be reported*/95); } nextch(); ptr = root; if (!isNames(ch)) { if (!isSep(ch)) return ptr; /* Allow optional SEPARATOR after ROOT */ get_pos(&fp_firstsep); nextch(); } fImplicitPrefix = fFalse; #else if (0) { #endif } else { if ((pfx_flags & PFX_ANON) && (isSep(ch) || (pcs->dash_for_anon_wall_station && ch == '-'))) { int first_ch = ch; filepos here; get_pos(&here); nextch(); if (isBlank(ch) || isEol(ch)) { if (!isSep(first_ch)) goto anon_wall_station; /* A single separator alone ('.' by default) is an anonymous * station which is on a point inside the passage and implies * the leg to it is a splay. */ if (TSTBIT(pcs->flags, FLAGS_ANON_ONE_END)) { set_pos(&here); compile_diagnostic(DIAG_ERR|DIAG_TOKEN, /*Can't have a leg between two anonymous stations*/3); LONGJMP(file.jbSkipLine); } pcs->flags |= BIT(FLAGS_ANON_ONE_END) | BIT(FLAGS_IMPLICIT_SPLAY); return new_anon_station(); } if (isSep(first_ch) && ch == first_ch) { nextch(); if (isBlank(ch) || isEol(ch)) { /* A double separator ('..' by default) is an anonymous station * which is on the wall and implies the leg to it is a splay. */ prefix * pfx; anon_wall_station: if (TSTBIT(pcs->flags, FLAGS_ANON_ONE_END)) { set_pos(&here); compile_diagnostic(DIAG_ERR|DIAG_TOKEN, /*Can't have a leg between two anonymous stations*/3); LONGJMP(file.jbSkipLine); } pcs->flags |= BIT(FLAGS_ANON_ONE_END) | BIT(FLAGS_IMPLICIT_SPLAY); pfx = new_anon_station(); pfx->sflags |= BIT(SFLAGS_WALL); return pfx; } if (ch == first_ch) { nextch(); if (isBlank(ch) || isEol(ch)) { /* A triple separator ('...' by default) is an anonymous * station, but otherwise not handled specially (e.g. for * a single leg down an unexplored side passage to a station * which isn't refindable). */ if (TSTBIT(pcs->flags, FLAGS_ANON_ONE_END)) { set_pos(&here); compile_diagnostic(DIAG_ERR|DIAG_TOKEN, /*Can't have a leg between two anonymous stations*/3); LONGJMP(file.jbSkipLine); } pcs->flags |= BIT(FLAGS_ANON_ONE_END); return new_anon_station(); } } } set_pos(&here); } ptr = pcs->Prefix; } i = 0; name = NULL; do { fNew = fFalse; if (name == NULL) { /* Need a new name buffer */ name = osmalloc(name_len); } /* i==0 iff this is the first pass */ if (i) { i = 0; nextch(); } while (isNames(ch)) { if (i < pcs->Truncate) { /* truncate name */ name[i++] = (pcs->Case == LOWER ? tolower(ch) : (pcs->Case == OFF ? ch : toupper(ch))); if (i >= name_len) { name_len = name_len + name_len; name = osrealloc(name, name_len); } } nextch(); } if (isSep(ch)) { fImplicitPrefix = fFalse; get_pos(&fp_firstsep); } if (i == 0) { osfree(name); if (!f_optional) { if (isEol(ch)) { if (fSurvey) { compile_diagnostic(DIAG_ERR|DIAG_COL, /*Expecting survey name*/89); } else { compile_diagnostic(DIAG_ERR|DIAG_COL, /*Expecting station name*/28); } } else { /* TRANSLATORS: Here "station" is a survey station, not a train station. */ compile_diagnostic(DIAG_ERR|DIAG_COL, /*Character “%c” not allowed in station name (use *SET NAMES to set allowed characters)*/7, ch); } LONGJMP(file.jbSkipLine); } return (prefix *)NULL; } name[i++] = '\0'; back_ptr = ptr; ptr = ptr->down; if (ptr == NULL) { /* Special case first time around at each level */ name = osrealloc(name, i); ptr = osnew(prefix); ptr->ident = name; name = NULL; ptr->right = ptr->down = NULL; ptr->pos = NULL; ptr->shape = 0; ptr->stn = NULL; ptr->up = back_ptr; ptr->filename = file.filename; ptr->line = file.line; ptr->min_export = ptr->max_export = 0; ptr->sflags = BIT(SFLAGS_SURVEY); if (fSuspectTypo && !fImplicitPrefix) ptr->sflags |= BIT(SFLAGS_SUSPECTTYPO); back_ptr->down = ptr; fNew = fTrue; } else { /* Use caching to speed up adding an increasing sequence to a * large survey */ static prefix *cached_survey = NULL, *cached_station = NULL; prefix *ptrPrev = NULL; int cmp = 1; /* result of strcmp ( -ve for <, 0 for =, +ve for > ) */ if (cached_survey == back_ptr) { cmp = strcmp(cached_station->ident, name); if (cmp <= 0) ptr = cached_station; } while (ptr && (cmp = strcmp(ptr->ident, name))<0) { ptrPrev = ptr; ptr = ptr->right; } if (cmp) { /* ie we got to one that was higher, or the end */ prefix *newptr; name = osrealloc(name, i); newptr = osnew(prefix); newptr->ident = name; name = NULL; if (ptrPrev == NULL) back_ptr->down = newptr; else ptrPrev->right = newptr; newptr->right = ptr; newptr->down = NULL; newptr->pos = NULL; newptr->shape = 0; newptr->stn = NULL; newptr->up = back_ptr; newptr->filename = file.filename; newptr->line = file.line; newptr->min_export = newptr->max_export = 0; newptr->sflags = BIT(SFLAGS_SURVEY); if (fSuspectTypo && !fImplicitPrefix) newptr->sflags |= BIT(SFLAGS_SUSPECTTYPO); ptr = newptr; fNew = fTrue; } cached_survey = back_ptr; cached_station = ptr; } depth++; f_optional = fFalse; /* disallow after first level */ if (isSep(ch)) get_pos(&fp_firstsep); } while (isSep(ch)); if (name) osfree(name); /* don't warn about a station that is referred to twice */ if (!fNew) ptr->sflags &= ~BIT(SFLAGS_SUSPECTTYPO); if (fNew) { /* fNew means SFLAGS_SURVEY is currently set */ SVX_ASSERT(TSTBIT(ptr->sflags, SFLAGS_SURVEY)); if (!fSurvey) { ptr->sflags &= ~BIT(SFLAGS_SURVEY); if (TSTBIT(pcs->infer, INFER_EXPORTS)) ptr->min_export = USHRT_MAX; } } else { /* check that the same name isn't being used for a survey and station */ if (fSurvey ^ TSTBIT(ptr->sflags, SFLAGS_SURVEY)) { /* TRANSLATORS: Here "station" is a survey station, not a train station. * * Here "survey" is a "cave map" rather than list of questions - it should be * translated to the terminology that cavers using the language would use. */ compile_diagnostic(DIAG_ERR, /*“%s” can’t be both a station and a survey*/27, sprint_prefix(ptr)); } if (!fSurvey && TSTBIT(pcs->infer, INFER_EXPORTS)) ptr->min_export = USHRT_MAX; } /* check the export level */ #if 0 printf("R min %d max %d depth %d pfx %s\n", ptr->min_export, ptr->max_export, depth, sprint_prefix(ptr)); #endif if (ptr->min_export == 0 || ptr->min_export == USHRT_MAX) { if (depth > ptr->max_export) ptr->max_export = depth; } else if (ptr->max_export < depth) { prefix *survey = ptr; char *s; const char *p; int level; for (level = ptr->max_export + 1; level; level--) { survey = survey->up; SVX_ASSERT(survey); } s = osstrdup(sprint_prefix(survey)); p = sprint_prefix(ptr); if (survey->filename) { compile_diagnostic_pfx(DIAG_ERR, survey, /*Station “%s” not exported from survey “%s”*/26, p, s); } else { compile_diagnostic(DIAG_ERR, /*Station “%s” not exported from survey “%s”*/26, p, s); } osfree(s); #if 0 printf(" *** pfx %s warning not exported enough depth %d " "ptr->max_export %d\n", sprint_prefix(ptr), depth, ptr->max_export); #endif } if (!fImplicitPrefix && (pfx_flags & PFX_WARN_SEPARATOR)) { filepos fp_tmp; get_pos(&fp_tmp); set_pos(&fp_firstsep); compile_diagnostic(DIAG_WARN|DIAG_COL, /*Separator in survey name*/392); set_pos(&fp_tmp); } return ptr; } /* if numeric expr is omitted: if f_optional return HUGE_REAL, else longjmp */ static real read_number(bool f_optional) { bool fPositive, fDigits = fFalse; real n = (real)0.0; filepos fp; int ch_old; get_pos(&fp); ch_old = ch; fPositive = !isMinus(ch); if (isSign(ch)) nextch(); while (isdigit(ch)) { n = n * (real)10.0 + (char)(ch - '0'); nextch(); fDigits = fTrue; } if (isDecimal(ch)) { real mult = (real)1.0; nextch(); while (isdigit(ch)) { mult *= (real).1; n += (char)(ch - '0') * mult; fDigits = fTrue; nextch(); } } /* !'fRead' => !fDigits so fDigits => 'fRead' */ if (fDigits) return (fPositive ? n : -n); /* didn't read a valid number. If it's optional, reset filepos & return */ set_pos(&fp); if (f_optional) { return HUGE_REAL; } if (isOmit(ch_old)) { compile_diagnostic(DIAG_ERR|DIAG_COL, /*Field may not be omitted*/8); } else { compile_diagnostic_token_show(DIAG_ERR, /*Expecting numeric field, found “%s”*/9); } LONGJMP(file.jbSkipLine); return 0.0; /* for brain-fried compilers */ }