2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-09-01 14:55:30 +00:00

Add support for parsing enumerations.

This commit is contained in:
Ted Lemon
2000-12-29 06:45:49 +00:00
parent 3a9992b455
commit 42c6a80350

View File

@@ -43,11 +43,50 @@
#ifndef lint #ifndef lint
static char copyright[] = static char copyright[] =
"$Id: parse.c,v 1.93 2000/12/28 23:18:36 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n"; "$Id: parse.c,v 1.94 2000/12/29 06:45:49 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
/* Enumerations can be specified in option formats, and are used for
parsing, so we define the routines that manage them here. */
struct enumeration *enumerations;
void add_enumeration (struct enumeration *enumeration)
{
enumeration -> next = enumerations;
enumerations = enumeration;
}
struct enumeration *find_enumeration (const char *name, int length)
{
struct enumeration *e;
for (e = enumerations; e; e = e -> next)
if (strlen (e -> name) == length &&
!memcmp (e -> name, name, (unsigned)length))
return e;
return (struct enumeration *)0;
}
struct enumeration_value *find_enumeration_value (const char *name,
int length,
const char *value)
{
struct enumeration *e;
int i;
e = find_enumeration (name, length);
if (e) {
for (i = 0; e -> values [i].name; i++) {
if (!strcmp (value, e -> values [i].name))
return &e -> values [i];
}
}
return (struct enumeration_value *)0;
}
/* Skip to the semicolon ending the current statement. If we encounter /* Skip to the semicolon ending the current statement. If we encounter
braces, the matching closing brace terminates the statement. If we braces, the matching closing brace terminates the statement. If we
encounter a right brace but haven't encountered a left brace, return encounter a right brace but haven't encountered a left brace, return
@@ -4143,6 +4182,8 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
unsigned char *ob; unsigned char *ob;
struct iaddr addr; struct iaddr addr;
int num; int num;
const char *f;
struct enumeration_value *e;
switch (*fmt) { switch (*fmt) {
case 'U': case 'U':
@@ -4209,6 +4250,31 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
log_fatal ("No memory for concatenation"); log_fatal ("No memory for concatenation");
break; break;
case 'N':
f = fmt;
fmt = strchr (fmt, '.');
if (!fmt) {
parse_warn (cfile, "malformed %s (bug!)",
"enumeration format");
foo:
skip_to_semi (cfile);
return 0;
}
token = next_token (&val, cfile);
if (!is_identifier (token)) {
parse_warn (cfile,
"identifier expected");
goto foo;
}
e = find_enumeration_value (f, fmt - f, val);
if (!e) {
parse_warn (cfile, "unknown value");
goto foo;
}
if (!make_const_data (&t, &e -> value, 1, 0, 1))
return 0;
break;
case 'I': /* IP address or hostname. */ case 'I': /* IP address or hostname. */
if (lookups) { if (lookups) {
if (!parse_ip_addr_or_hostname (&t, cfile, uniform)) if (!parse_ip_addr_or_hostname (&t, cfile, uniform))
@@ -4326,7 +4392,7 @@ int parse_option_decl (oc, cfile)
u_int8_t buf [4]; u_int8_t buf [4];
u_int8_t hunkbuf [1024]; u_int8_t hunkbuf [1024];
unsigned hunkix = 0; unsigned hunkix = 0;
const char *fmt; const char *fmt, *f;
struct option *option; struct option *option;
struct iaddr ip_addr; struct iaddr ip_addr;
u_int8_t *dp; u_int8_t *dp;
@@ -4334,6 +4400,7 @@ int parse_option_decl (oc, cfile)
int nul_term = 0; int nul_term = 0;
struct buffer *bp; struct buffer *bp;
int known = 0; int known = 0;
struct enumeration_value *e;
option = parse_option_name (cfile, 0, &known); option = parse_option_name (cfile, 0, &known);
if (!option) if (!option)
@@ -4386,6 +4453,33 @@ int parse_option_decl (oc, cfile)
hunkix += len; hunkix += len;
break; break;
case 'N':
f = fmt;
fmt = strchr (fmt, '.');
if (!fmt) {
parse_warn (cfile,
"malformed %s (bug!)",
"enumeration format");
foo:
skip_to_semi (cfile);
return 0;
}
token = next_token (&val, cfile);
if (!is_identifier (token)) {
parse_warn (cfile,
"identifier expected");
goto foo;
}
e = find_enumeration_value (f, fmt - f, val);
if (!e) {
parse_warn (cfile,
"unknown value");
goto foo;
}
len = 1;
dp = &e -> value;
goto alloc;
case 'I': /* IP address. */ case 'I': /* IP address. */
if (!parse_ip_addr (cfile, &ip_addr)) if (!parse_ip_addr (cfile, &ip_addr))
return 0; return 0;