static const fnode * next_format0 (fnode * f) { const fnode *r; if (f == NULL) return NULL; if (f->format != FMT_LPAREN) { f->count++; if (f->count <= f->repeat) return f; f->count = 0; return NULL; } /* Deal with a parenthesis node with unlimited format. */ if (f->repeat == -2) /* -2 signifies unlimited. */ for (;;) { if (f->current == NULL) f->current = f->u.child; for (; f->current != NULL; f->current = f->current->next) { r = next_format0 (f->current); if (r != NULL) return r; } } /* Deal with a parenthesis node with specific repeat count. */ for (; f->count < f->repeat; f->count++) { if (f->current == NULL) f->current = f->u.child; for (; f->current != NULL; f->current = f->current->next) { r = next_format0 (f->current); if (r != NULL) return r; } } f->count = 0; return NULL; }
fnode * next_format (void) { format_token t; fnode *f; if (saved_format != NULL) { /* Deal with a pushed-back format node */ f = saved_format; saved_format = NULL; goto done; } f = next_format0 (&array[0]); if (f == NULL) { if (!reversion_ok) { return NULL; } reversion_ok = 0; revert (); f = next_format0 (&array[0]); if (f == NULL) { format_error (NULL, reversion_error); return NULL; } /* Push the first reverted token and return a colon node in case * there are no more data items. */ saved_format = f; return &colon_node; } /* If this is a data edit descriptor, then reversion has become OK. */ done: t = f->format; if (!reversion_ok && (t == FMT_I || t == FMT_B || t == FMT_O || t == FMT_Z || t == FMT_F || t == FMT_E || t == FMT_EN || t == FMT_ES || t == FMT_G || t == FMT_L || t == FMT_A || t == FMT_D)) reversion_ok = 1; return f; }
const fnode * next_format (st_parameter_dt *dtp) { format_token t; const fnode *f; format_data *fmt = dtp->u.p.fmt; if (fmt->saved_format != NULL) { /* Deal with a pushed-back format node */ f = fmt->saved_format; fmt->saved_format = NULL; goto done; } f = next_format0 (&fmt->array.array[0]); if (f == NULL) { if (!fmt->reversion_ok) return NULL; fmt->reversion_ok = 0; revert (dtp); f = next_format0 (&fmt->array.array[0]); if (f == NULL) { format_error (dtp, NULL, reversion_error); return NULL; } /* Push the first reverted token and return a colon node in case * there are no more data items. */ fmt->saved_format = f; return &colon_node; } /* If this is a data edit descriptor, then reversion has become OK. */ done: t = f->format; if (!fmt->reversion_ok && (t == FMT_I || t == FMT_B || t == FMT_O || t == FMT_Z || t == FMT_F || t == FMT_E || t == FMT_EN || t == FMT_ES || t == FMT_G || t == FMT_L || t == FMT_A || t == FMT_D)) fmt->reversion_ok = 1; return f; }
static const fnode * next_format0 (fnode * f) { const fnode *r; if (f == NULL) return NULL; if (f->format != FMT_LPAREN) { f->count++; if (f->count <= f->repeat) return f; f->count = 0; return NULL; } /* Deal with a parenthesis node */ for (; f->count < f->repeat; f->count++) { if (f->current == NULL) f->current = f->u.child; for (; f->current != NULL; f->current = f->current->next) { r = next_format0 (f->current); if (r != NULL) return r; } } f->count = 0; return NULL; }