topo_parse.c revision 18fdaaef96cf74126ff84be8aa0b50a701a3f374
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <alloca.h>
#include "topo_impl.h"
#include "topo_enum.h"
#define TOPO_FILE "platform.topo"
#define TOPO_SHARE_DIRECTIVE "share"
void (*Outmethod)(const char *);
void
{
}
void
topo_fini(void)
{
}
void
topo_reset(void)
{
}
void
{
}
}
}
/*
* The PLATFRU property is special. It is inherited by static nodes
* automatically from their parent, if it is not set within the .topo
* file. For the root node, the node name itself is the PLATFRU value.
*/
static void
{
const char *pv;
int inst;
continue;
}
continue;
}
continue;
}
} else {
}
}
}
struct tnode *
topo_root(void)
{
return (root);
return (root);
}
static void syntax_error(const char *, int);
static void toolong_error(const char *, int);
int Empty = 0;
struct tnode *
{
char *parsebuf;
int line = 0;
return (NULL);
return (NULL);
line++;
if (*parsebuf == '\0' ||
int c;
;
continue;
}
}
}
topo_close(fp);
return (root);
}
struct tnode *
{
}
#define UPPER_MAX_RECURSE 10
#define DFLT_MAX_RECURSE 5
int Topo_max_recurse = DFLT_MAX_RECURSE;
void
{
newdepth);
return;
}
}
void
{
static int recurse_depth = 0;
char *filenmbuf;
if (++recurse_depth > Topo_max_recurse) {
return;
}
}
/*
* Declare a syntax error on the current line
*/
void
{
}
/*
* Declare the current line too long
*/
void
{
}
/*
* Skip whitespace, return pointer to start of next token
*/
char *
topo_whiteskip(char *srcbuf)
{
char *t;
return (NULL);
while (*t == ' ' || *t == '\t')
t++;
if (*t == '\0' || *t == '#' || *t == '\n')
return (NULL);
else
return (t);
}
int
{
char *b;
char *e;
char s;
long l;
errno = 0;
if (errno != 0)
return (-1);
*instno = (int)l;
return (0);
}
if (*src++ != '[')
return (-1);
b = src;
e = b;
while (isdigit(*e) != 0)
e++;
s = *e;
*e = '\0';
errno = 0;
*e = s;
if (errno != 0)
return (-1);
if (*e == ']') {
return (0);
}
if (*e++ != '-')
return (-1);
*min = (int)l;
b = e;
while (isdigit(*e) != 0)
e++;
s = *e;
*e = '\0';
errno = 0;
*e = s;
if (errno != 0)
return (-1);
if (*e++ != ']')
return (-1);
if (*e != '\0')
return (-1);
*max = (int)l;
return (0);
}
char *
{
char *b = src;
char *e;
char s;
return (NULL);
b++; /* skip leading slash */
e = b;
while (isalpha(*e) != 0 || *e == '_')
e++;
if (*e == '\0' || *e == '\n')
return (NULL);
s = *e;
*e = '\0';
*name = topo_strdup(b);
*e = s;
/* rest up to next slash is instance part */
b = e;
while (*e != '\0' && *e != '\n' && *e != '/')
e++;
s = *e;
*e = '\0';
*inst = topo_strdup(b);
*e = s;
return (e);
}
static int
{
char *b = src;
char *e;
char s;
int quoted = 0;
b = e = src;
/* property name must start with alpha character, _ or . */
return (-1);
e++;
e++;
if (*e == '\0' || *e == '\n')
return (-1);
s = *e;
*e = '\0';
*name = topo_strdup(b);
*e = s;
b = topo_whiteskip(e);
if (b == NULL || *b != '=') {
return (-1);
}
b = topo_whiteskip(++b);
if (*b == '"') {
b++;
quoted++;
}
e = b;
if (quoted) {
while (*e != '"' && *e != '\0' && *e != '\n')
e++;
if (*e != '"') {
return (-1);
}
} else {
while (*e != '\0' && *e != '\n' && *e != ' ' && *e != '\t')
e++;
}
s = *e;
*e = '\0';
*val = topo_strdup(b);
*e = s;
if (quoted)
e++;
b = topo_whiteskip(e);
if (b != NULL) {
return (-1);
}
return (0);
}
/*
* Add a child to 'parent' with name and instance number
* described by 'name' and 'inst'. If one already exists,
* just return a pointer to the existing one.
*/
static struct tnode *
{
return (NULL);
continue;
break;
break;
}
return (tmp);
if (instno >= 0)
else
return (tmp);
}
static struct tnode *
{
struct tnode *n;
char *cont;
return (root);
}
return (NULL);
}
/*
* If the node specifies a dynamic range, there may be a .topo
* file associated with the node type describing a hierarchy
* of possible nodes under this node.
*/
if (topo_get_instance_num(n) < 0)
}
struct tnode *
{
return (NULL);
return (NULL);
return (addto);
}
struct tnode *
{
char *alias;
char *b, *e;
char s;
/* Skip exclamation declaring a directive, and any following space */
b = e = topo_whiteskip(++buf);
/* directive must start with alpha character or _ */
if (isalpha(*e) == 0 && *e != '_')
return (NULL);
e++;
while (isalpha(*e) != 0 || *e == '_')
e++;
/*
* Presently we only have one valid directive. If we add more
* we should add a jump-table sort of structure.
*/
s = *e;
*e = '\0';
if (strcmp(TOPO_SHARE_DIRECTIVE, b) == 0) {
*e = s;
if (*e == '\0' || *e == '\n')
return (NULL);
b = e = topo_whiteskip(e);
e++;
while (isalpha(*e) != 0 || *e == '_')
e++;
/* No enumerator provided to share */
if (b == e)
return (NULL);
s = *e;
*e = '\0';
alias = topo_strdup(b);
*e = s;
return (rnode);
}
*e = s;
return (NULL);
}
struct tnode *
{
char *t;
Empty = 1;
return (NULL);
}
Empty = 0;
if (*t == '/')
/* a new path to add, growpath returns the leaf node */
if (*t == '!')
/* a directive is (probably) present in the topology file */
return (consume_directive(t, root));
return (consume_prop(t, lastleaf));
}