/*
* 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 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include "xlator.h"
#include "util.h"
#include "bucket.h"
#include "errlog.h"
/* Statics: */
#define FALSE 0
static int N_lists;
static void start_new_list(const bucket_t *);
static void grow_lists(void);
static bucket_t *new_bucket(const char *, int);
static void print_iface(const Interface *);
static void new_hashmap(void);
static int add_to_hashmap(const char *, const bucket_t *);
static bucket_t *find_in_hashmap(const char *);
/*
* initialization interfaces.
*/
/*
* create_lists -- initialize the bucket list and hash map.
*/
void
create_lists(void)
{
new_hashmap();
"list of versions");
}
}
/*
* data-loading interfaces -- adding buckets to lists and
* interfaces to buckets.
*/
/*
* add_parent -- add a parent node. Returns TRUE or FALSE.
*
* if *version == NULL, then
* the bucket version (eg, SUNW_1.1) hasn't
* been parsed correctly. Die.
* if *after == NULL, then this is the ``initial case'',
* where no predecessor (child) exists. We start a new
* tree of buckets.
* if *after != NULL, we have the normal case, and
* add to an existing tree.
* if *after is not a version name found among the buckets,
* then something got misparsed or the versions file is
* malformed. Function will print problem and
* return 0 so caller can report location of error.
* If either version or after is NULL, it's a programmer error.
*/
int
{
/* Sanity-check parameters. */
/* We don't have one have one yet. */
}
if (*after == '\0') {
/*
* This is the ``initial case'', where no
* child exists. We start a new tree of buckets.
*/
} else {
/*
* The version in the spec doesn't appear in the
* versions file. One or the other is lying.
*/
"therefor can't add it's parent, \"%s\"",
return (FALSE);
}
}
return (TRUE);
}
/*
* add_uncle -- adds an uncle node
*/
int
{
/* Sanity-check parameters. */
/* We don't have one have one yet. */
}
if (*after == '\0') {
/*
* This is the ``initial case'', where no
* child exists. We start a new tree of buckets.
*/
} else {
/*
* The version in the spec doesn't appear in the
* versions file. One or the other is lying.
*/
"therefor can't add it's uncle, \"%s\"",
return (FALSE);
}
}
return (TRUE);
}
/*
* set_weak -- set a version to be a weak version
*/
void
{
bucket_t *v;
/* We don't have one have one yet. */
}
}
/*
* add_by_name -- look up bucket and add an interface to it.
* Returns 0 for success or an errno.h value for failure.
*
* if *version is not among the buckets, then the
* version in the spec doesn't appear in the
* set file. One or the other is lying. Function will
* report the problem and return ENOENT
* so the front end can report and exit (or
* continue if it wants).
* if interface ore version is NULL, then
* the begin line code should
* have caught it long before, to avoid passing
* a null pointer around. Die.
*
*/
int
{
bucket_t *b;
/* Sanity-check the parameters. */
/*
* The version in the spec doesn't appear in the
* versions file. Alas, this isn't an error. It can
* happen whenever doing just sparc, just i386
* or the like.
*/
return (ENOENT);
}
/*
* Add to bucket.
*/
}
}
} else if (interface->IF_auxiliary) {
} else if (IsFilterLib) {
/*
* For DATA types it is currently assumed that they are
* handled via a minimal C file, e.g. 'data.c', in the
* library's build. Hence, we do not append '= DATA' here.
*/
}
}
switch (interface->IF_binding) {
case DIRECT:
break;
case NODIRECT:
break;
}
/* Assign in case of realloc. */
b->b_protected_table =
b->b_has_protecteds = 1;
} else {
/* Assign in case of realloc. */
buffer);
}
return (0);
}
/*
* Processing interfaces
*/
/*
* sort_buckets -- sort the interfaces within the buckets into
* alphabetical order.
*/
void
sort_buckets(void)
{
bucket_t *l, *b;
if (b->b_uncles) {
}
}
}
}
}
/*
* add_local -- set the local flag on the logically first bucket.
* This decision may belong in the caller, as it is about
* mapfiles, not inherent ordering or bucket contents...
*/
void
add_local(void)
{
int done = 0;
/* Iterate across lists of buckets */
/* Traverse the list found. */
if (b->b_weak != 1) {
/* We've found the first non-weak. */
"set has_locals on bucket 0x%p", b);
break;
}
}
break;
}
if (done == 0) {
}
}
/*
* Output interfaces, mostly iterators
*/
/*
* parents_of -- return a list of all parents.
*/
char **
{
char **p = &a[0];
a[0] = '\0';
/* Go to parent, print it and all its uncle. */
return (a);
}
b = b->b_parent;
*p++ = b->b_name;
*p = '\0';
return (a);
}
/*
* first, next_from_bucket --iterators for bucket contents. Serially
* reusable only.
*/
/*
* debugging interfaces
*/
void
{
(void *)b->b_parent);
(void *)b->b_uncles);
(void *)b->b_thread);
b->b_has_locals);
b->b_has_protecteds);
b->b_was_printed);
b->b_weak);
(void *)b->b_global_table);
(void *)b->b_protected_table);
}
void
print_all_buckets(void)
{
bucket_t *l, *b;
int i = 0, j = 0;
char **p;
for (j = 0, b = first_from_list(l);
b != NULL; b = next_from_list(), ++j) {
print_bucket(b);
}
if (b->b_uncles) {
}
}
}
}
/*
* lower-level functions, not visible outside the file.
*/
/*
* new_bucket -- create a bucket for a given version. Must not fail.
*/
static bucket_t *
{
bucket_t *b;
"to store interfaces in");
}
"in a version bucket");
}
return (b);
}
/*
* start_new_list -- start a list of buckets.
*/
static void
{
int i;
continue;
if (i >= N_lists) {
grow_lists();
}
Buckethead[i] = (bucket_t *)b;
}
/*
* grow_list -- make more lists. This should never occur...
*/
static void
grow_lists(void)
{
int i = N_lists;
"required (< %d is normal). Check sets file "
"to see why so many lines appear.",
N_lists *= 2;
== NULL) {
"version buckets");
}
for (; i < N_lists; ++i) {
Buckethead[i] = NULL;
}
}
/*
* delete_lists -- clean up afterwards.
*/
void
delete_lists(void)
{
N_lists = 0;
Buckethead = 0;
}
/*
* first_list, next_list -- an iterator for lists themselves. Serially
* reusable only.
*/
bucket_t *
first_list(void)
{
Bc = 0;
return (Buckethead[Bc]);
}
bucket_t *
next_list(void)
{
return (Buckethead[++Bc]);
}
/*
* first, next, last_from_list -- iterators for individual lists. Serially
* reusable only.
*/
bucket_t *
{
}
bucket_t *
next_from_list(void)
{
}
/*
* Iface print utility
*/
static void
{
p->IF_binding);
}
static struct {
int hh_map_size;
int hh_mapC;
} Hashhead = {
};
static int checksum(const char *);
static void print_hashmap(const hashmap_t *);
/*
* new_hashmap -- create the hash.
*/
static void
new_hashmap(void)
{
== NULL) {
"the versions");
}
}
/*
* add_to_hashmap -- add a bucket to the map. This is strictly for
* use by add_parent()/add_uncle().
*/
static int
{
hashmap_t *p;
"Hashead.map was null in add_to_hashmap");
"mapC too big in add_to_hashmap");
/* Seen for the second time. TBD... */
return (ERR);
}
}
print_hashmap(p);
return (0);
}
/*
* find_in_hashmap -- find a bucket by name. Strictly for use by addByName().
*/
static bucket_t *
{
"Hashhead.hh_map was null in find_in_hashmap");
}
/* Found it */
}
}
/* Doesn't exist, meaning version name is bogus. */
return (NULL);
}
/*
* checksum -- from sum(1), algorithm 1.
*/
static int
checksum(const char *p)
{
int sum;
if (sum & 01)
else
sum >>= 1;
sum += *p;
sum &= 0xFFFF;
}
return (sum);
}
static void
{
h->h_version_name);
(void *) h->h_bucket);
}