return st->buffer[0];
}
-#define GETC(st) \
- ((st)->p < (st)->pend ? *(st)->p++ : get_byte (st))
+#define GETC(st) ((st)->p < (st)->pend ? *(st)->p++ : get_byte (st))
-
-#define UNGETC(c, st) \
- (*--(st)->p = (c))
+#define UNGETC(c, st) (--((st)->p))
/** Mapping table for reading a number. Hexadecimal chars
(0..9,A..F,a..F) are mapped to the corresponding numbers.
for the next element. */
static MPlist *
-read_mtext_element (MPlist *plist, MStream *st)
+read_mtext_element (MPlist *plist, MStream *st, int skip)
{
unsigned char buffer[1024];
int bufsize = 1024;
c = escape_mnemonic[c];
}
- buf[i++] = c;
+ if (! skip)
+ buf[i++] = c;
}
- MPLIST_SET_ADVANCE (plist, Mtext,
- mtext__from_data (buf, i, MTEXT_FORMAT_UTF_8, 1));
- if (buf != buffer)
- free (buf);
+ if (! skip)
+ {
+ MPLIST_SET_ADVANCE (plist, Mtext,
+ mtext__from_data (buf, i, MTEXT_FORMAT_UTF_8, 1));
+ if (buf != buffer)
+ free (buf);
+ }
return plist;
}
read the character C. */
static MPlist *
-read_integer_element (MPlist *plist, MStream *st, int c)
+read_integer_element (MPlist *plist, MStream *st, int c, int skip)
{
int num;
else
num = read_decimal (st, c);
- MPLIST_SET_ADVANCE (plist, Minteger, (void *) num);
+ if (! skip)
+ MPLIST_SET_ADVANCE (plist, Minteger, (void *) num);
return plist;
}
for the next element. */
static MPlist *
-read_symbol_element (MPlist *plist, MStream *st)
+read_symbol_element (MPlist *plist, MStream *st, int skip)
{
unsigned char buffer[1024];
int bufsize = 1024;
break;
c = escape_mnemonic[c];
}
- buf[i++] = c;
+ if (! skip)
+ buf[i++] = c;
}
- buf[i] = 0;
- MPLIST_SET_ADVANCE (plist, Msymbol, msymbol ((char *) buf));
- if (buf != buffer)
- free (buf);
if (c > ' ')
UNGETC (c, st);
+ if (! skip)
+ {
+ buf[i] = 0;
+ MPLIST_SET_ADVANCE (plist, Msymbol, msymbol ((char *) buf));
+ if (buf != buffer)
+ free (buf);
+ }
return plist;
}
'0'..'9', '-': integer
'?': integer representing character code
the other ASCII letters: symbol
-*/
+
+ If KEYS is not NULL, it is a plist contains target keys and stop
+ keys. In this caes, read only a plist whose key has value 1 in
+ KEYS, and return NULL when we encounter a plist whose key has value
+ 0 in KEYS while skipping any other elements. */
static MPlist *
-read_element (MPlist *plist, MStream *st)
+read_element (MPlist *plist, MStream *st, MPlist *keys)
{
int c;
MPLIST_NEW (pl);
p = pl;
- while ((p = read_element (p, st)));
- MPLIST_SET_ADVANCE (plist, Mplist, pl);
+ p = read_element (p, st, NULL);
+ if (keys && p && MPLIST_SYMBOL_P (pl))
+ {
+ MPlist *p0 = keys;
+ MPLIST_FIND (p0, MPLIST_SYMBOL (pl));
+ if (! MPLIST_TAIL_P (p0) && ! MPLIST_VAL (p0))
+ {
+ M17N_OBJECT_UNREF (pl);
+ return NULL;
+ }
+ while ((p = read_element (p, st, NULL)));
+ if (! MPLIST_TAIL_P (p0))
+ MPLIST_SET_ADVANCE (plist, Mplist, pl);
+ else
+ M17N_OBJECT_UNREF (pl);
+ }
+ else
+ {
+ if (p)
+ while ((p = read_element (p, st, NULL)));
+ MPLIST_SET_ADVANCE (plist, Mplist, pl);
+ }
return plist;
}
if (c == '"')
- return read_mtext_element (plist, st);
+ return (read_mtext_element (plist, st, keys ? 1 : 0));
if ((c >= '0' && c <= '9') || c == '-' || c == '?' || c == '#')
- return read_integer_element (plist, st, c);
+ return (read_integer_element (plist, st, c, keys ? 1 : 0));
if (c == EOF || c == ')')
return NULL;
UNGETC (c, st);
- return read_symbol_element (plist, st);
+ return (read_symbol_element (plist, st, keys ? 1 : 0));
}
void
key = MPLIST_SYMBOL (plist);
plist = MPLIST_NEXT (plist);
type = MPLIST_KEY (plist);
- if (type->managing_key)
+ if (type->managing_key && MPLIST_VAL (plist))
M17N_OBJECT_REF (MPLIST_VAL (plist));
MPLIST_SET_ADVANCE (p, key, MPLIST_VAL (plist));
plist = MPLIST_NEXT (plist);
MPlist *
-mplist__from_file (FILE *fp)
+mplist__from_file (FILE *fp, MPlist *keys)
{
MPlist *plist, *pl;
MStream st;
st.p = st.pend = st.buffer;
MPLIST_NEW (plist);
pl = plist;
- while ((pl = read_element (pl, &st)));
+ while ((pl = read_element (pl, &st, keys)));
return plist;
}
st.pend = str + n;
MPLIST_NEW (plist);
pl = plist;
- while ((pl = read_element (pl, &st)));
+ while ((pl = read_element (pl, &st, NULL)));
return plist;
}
{
if (! MPLIST_TAIL_P (plist))
M17N_OBJECT_UNREF (MPLIST_VAL (plist));
- M17N_OBJECT_REF (val);
+ if (val)
+ M17N_OBJECT_REF (val);
}
MPLIST_SET (plist, key, val);
return plist;
if (key == Mnil)
MERROR (MERROR_PLIST, NULL);
MPLIST_FIND (plist, Mnil);
- if (key->managing_key)
+ if (val && key->managing_key)
M17N_OBJECT_REF (val);
MPLIST_KEY (plist) = key;
MPLIST_VAL (plist) = val;
MPLIST_VAL (pl) = MPLIST_VAL (plist);
MPLIST_NEXT (pl) = MPLIST_NEXT (plist);
plist->next = pl;
- if (key->managing_key)
+ if (val && key->managing_key)
M17N_OBJECT_REF (val);
MPLIST_KEY (plist) = key;
MPLIST_VAL (plist) = val;
key = MPLIST_KEY (plist);
M17N_OBJECT_UNREF (MPLIST_NEXT (plist));
MPLIST_KEY (plist) = Mnil;
- if (key->managing_key && MPLIST_VAL (plist))
+ if (key->managing_key)
M17N_OBJECT_UNREF (MPLIST_VAL (plist));
plist->next = NULL;
}
else
{
if (! MPLIST_TAIL_P (plist)
- && MPLIST_KEY (plist)->managing_key
- && MPLIST_VAL (plist))
+ && MPLIST_KEY (plist)->managing_key)
M17N_OBJECT_UNREF (MPLIST_VAL (plist));
- if (key->managing_key)
+ if (val && key->managing_key)
M17N_OBJECT_REF (val);
MPLIST_SET (plist, key, val);
}