X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/ba6e6b64033b1f9de49feccb5c9cd438354481f7..0f00dc4c8eb47e67bc0f148c2dd109f73a451e0a:/math/qdparse.c diff --git a/math/qdparse.c b/math/qdparse.c new file mode 100644 index 0000000..217cc62 --- /dev/null +++ b/math/qdparse.c @@ -0,0 +1,141 @@ +/* -*-c-*- + * + * Quick-and-dirty parser + * + * (c) 2004 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +/*----- Header files ------------------------------------------------------*/ + +#include +#include + +#include "qdparse.h" + +/*----- Main code ---------------------------------------------------------*/ + +/* --- @qd_skipspc@ --- * + * + * Arguments: @qd_parse *qd@ = context + * + * Returns: --- + * + * Use: Skips spaces in the string. No errors. + */ + +void qd_skipspc(qd_parse *qd) +{ + while (isspace((unsigned char)*qd->p)) + qd->p++; +} + +/* --- @qd_delim@ --- * + * + * Arguments: @qd_parse *qd@ = context + * @int ch@ = character to compare with + * + * Returns: Nonzero if it was, zero if it wasn't. + * + * Use: Checks the next (non-whitespace) character is what we + * expect. If it is, the character is eaten; otherwise it's no + * big deal. + */ + +int qd_delim(qd_parse *qd, int ch) +{ + qd_skipspc(qd); + if (*qd->p != ch) + return (0); + qd->p++; + return (1); +} + +/* --- @qd_enum@ --- * + * + * Arguments: @qd_parse *qd@ = context + * @const char *e@ = list of enum strings, space separated + * + * Returns: Index of the string matched, or @-1@. + * + * Use: Matches a keyword. + */ + +int qd_enum(qd_parse *qd, const char *e) +{ + size_t n; + int i = 0; + + qd_skipspc(qd); + for (;;) { + e += strspn(e, ", "); + if (!*e) break; + n = strcspn(e, ", "); + if (strncmp(qd->p, e, n) == 0 && !isalnum((unsigned char)qd->p[n])) { + qd->p += n; + return (i); + } + i++; e += n; + } + qd->e = "unrecognized keyword"; + return (-1); +} + +/* --- @qd_getmp@ --- * + * + * Arguments: @qd_parse *qd@ = context + * + * Returns: The integer extracted, or null. + * + * Use: Parses a multiprecision integer from a string. + */ + +mp *qd_getmp(qd_parse *qd) +{ + char *q; + mp *m; + + qd_skipspc(qd); + m = mp_readstring(MP_NEW, qd->p, &q, 0); + if (m && !isalnum((unsigned char)*q)) + qd->p = q; + else { + mp_drop(m); + qd->e = "bad number"; + } + return (m); +} + +/* --- @qd_eofp@ --- * + * + * Arguments: @qd_parse *qd@ = context + * + * Returns: Nonzero if at EOF, zero otherwise. + */ + +int qd_eofp(qd_parse *qd) +{ + qd_skipspc(qd); + return (!*qd->p); +} + +/*----- That's all, folks -------------------------------------------------*/