pn_transform_t *pn_transform() { static pn_class_t clazz = PN_CLASS(pn_transform); pn_transform_t *transform = (pn_transform_t *) pn_new(sizeof(pn_transform_t), &clazz); transform->rules = pn_list(0, PN_REFCOUNT); transform->matched = false; return transform; }
pn_rule_t *pn_rule(const char *pattern, const char *substitution) { static pn_class_t clazz = PN_CLASS(pn_rule); pn_rule_t *rule = (pn_rule_t *) pn_new(sizeof(pn_rule_t), &clazz); rule->pattern = pn_string(pattern); rule->substitution = pn_string(substitution); return rule; }
/* * NAME: parser->shift() * DESCRIPTION: perform a shift */ static void ps_shift(parser *ps, snode *sn, short token, char *text, ssizet len) { int n; n = srp_shift(ps->lr, sn->pn->state, token); if (n >= 0) { /* shift works: add new snode */ ps->states[n] = sn_add(&ps->list, sn, pn_new(&ps->pnc, token, n, text, len, sn->pn, (pnode *) NULL), ps->states[n]); return; } /* no shift: add node to free list */ sn_del(&ps->list, sn); }
pn_selectable_t *pni_selectable(ssize_t (*capacity)(pn_selectable_t *), ssize_t (*pending)(pn_selectable_t *), pn_timestamp_t (*deadline)(pn_selectable_t *), void (*readable)(pn_selectable_t *), void (*writable)(pn_selectable_t *), void (*expired)(pn_selectable_t *), void (*finalize)(pn_selectable_t *)) { static pn_class_t clazz = PN_CLASS(pn_selectable); pn_selectable_t *selectable = (pn_selectable_t *) pn_new(sizeof(pn_selectable_t), &clazz); selectable->capacity = capacity; selectable->pending = pending; selectable->readable = readable; selectable->deadline = deadline; selectable->writable = writable; selectable->expired = expired; selectable->finalize = finalize; return selectable; }
pni_entry_t *pni_store_put(pni_store_t *store, const char *address) { assert(store); static pn_class_t clazz = PN_CLASS(pni_entry); if (!address) address = ""; pni_stream_t *stream = pni_stream_put(store, address); if (!stream) return NULL; pni_entry_t *entry = (pni_entry_t *) pn_new(sizeof(pni_entry_t), &clazz); if (!entry) return NULL; entry->stream = stream; entry->free = false; entry->stream_next = NULL; entry->stream_prev = NULL; entry->store_next = NULL; entry->store_prev = NULL; entry->delivery = NULL; entry->bytes = pn_buffer(64); entry->status = PN_STATUS_UNKNOWN; LL_ADD(stream, stream, entry); LL_ADD(store, store, entry); store->size++; return entry; }
/* * NAME: parser->parse() * DESCRIPTION: parse a string, return a parse tangle */ static pnode *ps_parse(parser *ps, string *str, bool *toobig) { snode *sn; short n; snode *next; char *ttext; ssizet size, tlen; unsigned short nred; char *red; /* initialize */ size = str->len; ps->nstates = srp_check(ps->lr, 0, &nred, &red); if (ps->nstates < ps->nprod) { ps->nstates = ps->nprod; } ps->states = ALLOC(snode*, ps->nstates); memset(ps->states, '\0', ps->nstates * sizeof(snode*)); ps->list.first = (snode *) NULL; /* state 0 */ ps->states[0] = sn_new(&ps->list, pn_new(&ps->pnc, 0, 0, (char *) NULL, (ssizet) 0, (pnode *) NULL, (pnode *) NULL), (snode *) NULL); do { /* * apply reductions for current states, expanding states if needed */ for (sn = ps->list.first; sn != (snode *) NULL; sn = sn->next) { n = srp_check(ps->lr, sn->pn->state, &nred, &red); if (n < 0) { /* parser grown to big */ FREE(ps->states); *toobig = TRUE; return (pnode *) NULL; } if (n > ps->nstates) { unsigned short stsize; /* grow tables */ stsize = n; stsize <<= 1; ps->states = REALLOC(ps->states, snode*, ps->nstates, stsize); memset(ps->states + ps->nstates, '\0', (stsize - ps->nstates) * sizeof(snode*)); ps->nstates = stsize; } for (n = 0; n < nred; n++) { ps_reduce(ps, sn->pn, red); red += 4; if (ps->frame->rlim->ticks < 0) { if (ps->frame->rlim->noticks) { ps->frame->rlim->ticks = 0x7fffffff; } else { FREE(ps->states); error("Out of ticks"); } } } i_add_ticks(ps->frame, 1); } switch (n = dfa_scan(ps->fa, str, &size, &ttext, &tlen)) { case DFA_EOS: /* if end of string, return node from state 1 */ sn = ps->states[1]; FREE(ps->states); return (sn != (snode *) NULL) ? sn->pn : (pnode *) NULL; case DFA_REJECT: /* bad token */ FREE(ps->states); error("Bad token at offset %u", str->len - size); return (pnode *) NULL; case DFA_TOOBIG: FREE(ps->states); *toobig = TRUE; return (pnode *) NULL; default: /* shift */ memset(ps->states, '\0', ps->nstates * sizeof(snode*)); sn = ps->list.first; ps->list.first = (snode *) NULL; do { next = sn->next; ps_shift(ps, sn, n, ttext, tlen); sn = next; } while (sn != (snode *) NULL); } } while (ps->list.first != (snode *) NULL);
/* * NAME: parser->reduce() * DESCRIPTION: perform a reduction */ static void ps_reduce(parser *ps, pnode *pn, char *p) { snode *sn; pnode *next; unsigned short n; short symb; char *red; ssizet len; /* * get rule to reduce by */ red = ps->grammar->text + (UCHAR(p[0]) << 8) + UCHAR(p[1]); p += 2; symb = (UCHAR(p[0]) << 8) + UCHAR(p[1]); len = UCHAR(red[0]); /* * create reduce node */ next = pn; if (len == 0) { pn = (pnode *) NULL; } else { n = len; do { next = next->next; } while (--n != 0); } n = srp_goto(ps->lr, next->state, symb); pn = pn_new(&ps->pnc, symb, n, red, len, next, pn); /* * see if this reduction can be merged with another */ i_add_ticks(ps->frame, 2); for (sn = ps->states[n]; sn != (snode *) NULL; sn = sn->slist) { if (sn->pn->symbol == symb && sn->pn->next == next) { pnode **ppn; if (sn->pn->u.text != (char *) NULL) { /* first alternative */ sn->pn->list = pn_new(&ps->pnc, symb, n, sn->pn->u.text, sn->pn->len, (pnode *) NULL, sn->pn->list); sn->pn->u.text = (char *) NULL; sn->pn->len = 1; } /* add alternative */ for (ppn = &sn->pn->list; *ppn != (pnode *) NULL && (*ppn)->u.text < red; ppn = &(*ppn)->next) ; sn->pn->len++; pn->next = *ppn; *ppn = pn; return; } i_add_ticks(ps->frame, 1); } /* * new reduction */ ps->states[n] = sn_new(&ps->list, pn, ps->states[n]); }
pn_io_t *pn_io(void) { static pn_class_t clazz = PN_CLASS(pn_io); pn_io_t *io = (pn_io_t *) pn_new(sizeof(pn_io_t), &clazz); return io; }