- /*
 - * cpvparser1.c - test code for ksh93 compound variable parsing
 - *
 - *
 - * It basically reads the output of $ print -v ... # like this:
 - * ---- snip ----
 - * $ ksh93 -c 'compound c=( va=1 vb=hello ) ; print -v c'
 - * (
 - * va=1
 - * vb=hello
 - * )
 - * ---- snip ----
 - *
 - * ToDo:
 - * - typed member variables (compound c=(typeset -i num=4))
 - * - arrays (indexed, sparse indexed and associative)
 - * - multibyte characters
 - *
 - * Written by Roland Mainz <roland.mainz@nrubsig.org>
 - */
 - #include <stdlib.h>
 - #include <stdbool.h>
 - #include <string.h>
 - #include <stdio.h>
 - #include <ctype.h>
 - #define MAX_NAME_VAL_SIZE 1024
 - typedef struct cpv_name_val
 - {
 - const char *cpv_name;
 - const char *cpv_value;
 - } cpv_name_val;
 - /* prototypes */
 - static void free_cpv_name_val_data(cpv_name_val *cnv);
 - static int cpv_parse_name_val(const char **instr_ptr, cpv_name_val *cpv_nv);
 - static
 - int cpv_parse_name_val(const char **instr_ptr, cpv_name_val *cpv_nv)
 - {
 - char namebuff[MAX_NAME_VAL_SIZE];
 - char valbuff[MAX_NAME_VAL_SIZE];
 - const char *instr = *instr_ptr;
 - const char *s;
 - char *n;
 - char *v;
 - s = instr;
 - skipspaces:
 - s++;
 - /*
 - * skip POSIX-style '#' comments
 - * (allowed since this is based on POSIX sh(1) syntax)
 - */
 - if (*s == '#') {
 - s++;
 - while((*s != '\0') && (*s != '\n'))
 - s++;
 - goto skipspaces;
 - }
 - if (*s == '\0') {
 - return 1;
 - }
 - /* cpv == "( foo=bar blabla=text )"*/
 - if (*s == ')') {
 - return 1;
 - }
 - /*
 - * start parsing variable name
 - */
 - /*variable names MUST start with a letter! */
 - "parser error, first char in variable not "
 - "isalpha(c=%c)\n",
 - *s);
 - return 1;
 - }
 - n = namebuff;
 - *n++ = *s++;
 - *n = '\0';
 - if (*s != '=') {
 - *s);
 - return 1;
 - }
 - s++; /* skip '=' */
 - /*
 - * start parsing variable value
 - */
 - bool in_doublequotes=false;
 - bool in_singlequotes=false;
 - v = valbuff;
 - val_quotes:
 - if (in_singlequotes) {
 - while(*s != '\0') {
 - if (*s == '\'') {
 - in_singlequotes = false;
 - s++;
 - goto val_quotes;
 - }
 - if ((*s == '\\') && (*(s+1) != '\0')) {
 - /*
 - * fixme: should support \ooo octals,
 - * \u[hex] unicode and \w[hex] wchar
 - */
 - s++;
 - }
 - *v++ = *s++;
 - }
 - }
 - else if (in_doublequotes) {
 - while(*s != '\0') {
 - if (*s == '"') {
 - in_doublequotes = false;
 - s++;
 - goto val_quotes;
 - }
 - if ((*s == '\\') && (*(s+1) != '\0')) {
 - /*
 - * fixme: should support \ooo octals,
 - * \u[hex] unicode and \w[hex] wchar
 - */
 - s++;
 - }
 - *v++ = *s++;
 - }
 - }
 - else
 - {
 - if (*s == '"') {
 - in_doublequotes = true;
 - s++;
 - goto val_quotes;
 - }
 - if (*s == '\'') {
 - in_singlequotes = true;
 - s++;
 - goto val_quotes;
 - }
 - if ((*s == '\\') && (*(s+1) != '\0')) {
 - /*
 - * fixme: should support \ooo octals,
 - * \u[hex] unicode and \w[hex] wchar
 - */
 - s++;
 - }
 - *v++ = *s++;
 - }
 - }
 - if (in_singlequotes) {
 - return 1;
 - }
 - if (in_doublequotes) {
 - return 1;
 - }
 - *v = '\0';
 - // (void)printf("name='%s', value='%s'\n", namebuff, valbuff);
 - cpv_nv->cpv_name = strdup(namebuff);
 - cpv_nv->cpv_value = strdup(valbuff);
 - if ((cpv_nv->cpv_name == NULL) || (cpv_nv->cpv_value == NULL)) {
 - free_cpv_name_val_data(cpv_nv);
 - return 2;
 - }
 - *instr_ptr = s;
 - return 0;
 - }
 - void free_cpv_name_val_data(cpv_name_val *cnv)
 - {
 - cnv->cpv_name = NULL;
 - cnv->cpv_value = NULL;
 - }
 - int main(int ac, char *av[])
 - {
 - const char *str =
 - "x=y1 chicken=wing xchicken=w\\\"ing qcount=\"one two\" sq1='foo \" x \" bar'"
 - "\n # a comment x=y\n"
 - "\n"
 - " \n"
 - "\t\n"
 - "emptyval= "
 - "aftercomment=yep";
 - const char *s = str;
 - int i = 0;
 - cpv_name_val cnv[256];
 - for (i=0 ; cpv_parse_name_val(&s, &cnv[i]) == 0 ; i++) {
 - }
 - return EXIT_SUCCESS;
 - }
 
cpvparser1.c - test code for ksh93 compound variable parsing
Posted by Anonymous on Sat 18th Nov 2023 11:11
raw | new post
view followups (newest first): cpvparser1.c - test code for ksh93 compound variable parsing by Anonymous
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.
 nrubsig.kpaste.net RSS