/*
* Copyright (c) 2001, 2002, 2003, 2004, 2005 Netli, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: ncnf_dump.c,v 1.1 2005/05/26 12:08:19 vlm Exp $
*/
#include "headers.h"
#include "ncnf_int.h"
static void
_print_indent(FILE *f, int indent) {
while(indent--)
fprintf(f, " ");
}
/*
* Process value and insert necessary escaping.
*/
static void
_display_value(FILE *f, const char *value) {
int to_escape = 0;
const char *v;
for(v = value; *v; v++) {
switch(*v) {
default:
continue;
case '\\':
if(v != value)
continue;
case '"':
case '\n':
case '\v':
case '\f':
case '\r':
to_escape = 1;
}
break;
}
if(!to_escape) {
/* No escaping is necessary */
fwrite(value, v - value, 1, f);
return;
}
/* Print out the string, escaping certain characters */
for(v = value; *v; v++) {
switch(*v) {
case '\v': fputs("\\v", f); break;
case '\f': fputs("\\f", f); break;
case '\n': fputs("\\n", f); break;
case '\r': fputs("\\r", f); break;
case '"': fputs("\\\"", f); break;
case '\\': fputs("\\\\", f); break;
default:
if(v == value) {
fputc('\\', f);
if(v[0] != ' '
&& v[0] != '\n'
&& v[0] != '\r'
&& v[0] != '\t'
) fputc('\n', f);
}
fputc(*v, f);
}
}
}
void
_ncnf_obj_dump_recursive(FILE *f, struct ncnf_obj_s *obj,
const char *flatten_type, int marked_only,
int verbose, int indent, int indent_shift, int single_level,
int *ret_rsize
) {
int cc;
int recursive_size = sizeof(*obj);
assert(obj->obj_class != NOBJ_INVALID);
if(marked_only && !obj->mark) /* Skip unmarked entries */
return;
if(obj->obj_class != NOBJ_ROOT)
_print_indent(f, indent);
if(flatten_type) indent_shift = 0;
if(!flatten_type)
switch(obj->obj_class) {
case NOBJ_COMPLEX:
if(single_level) {
fprintf(f, "%s %s { ... }", obj->type, obj->value);
} else {
fprintf(f, "%s \"%s\" {", obj->type, obj->value);
}
if(verbose)
fprintf(f, "\t# line %d <%d> <%p>",
obj->config_line,
obj->obj_class,
obj
);
fputs("\n", f);
break;
case NOBJ_ATTRIBUTE:
if(single_level) {
fprintf(f, "%s\t", obj->type);
_display_value(f, obj->value);
} else {
fprintf(f, "%s \"", obj->type);
_display_value(f, obj->value);
fprintf(f, "\";");
}
if(verbose)
fprintf(f,
"\t# line %d\t<%d>",
obj->config_line,
obj->obj_class
);
fputs("\n", f);
break;
case NOBJ_REFERENCE:
if(single_level) {
fprintf(f, "%s %s => %s %s { ... }",
obj->type, obj->value,
obj->m_ref_type, obj->m_ref_value
);
} else {
fprintf(f, "%s %s \"%s\" = %s \"%s\";",
(obj->m_ref_flags & 1) ? "attach" : "ref",
obj->type, obj->value,
obj->m_ref_type, obj->m_ref_value
);
}
if(verbose)
fprintf(f,
"\t# line %d <%p>-><%p>",
obj->config_line,
obj,
_ncnf_real_object(obj)
);
fputs("\n", f);
break;
default:
/* Do nothing */
break;
}
if(!single_level)
switch(obj->obj_class) {
case NOBJ_ROOT:
case NOBJ_COMPLEX:
/* Count the overhead for collections */
for(cc = 0; cc < MAX_COLLECTIONS; cc++) {
collection_t *coll = &obj->m_collection[cc];
int i;
/* Count the overhead */
recursive_size += coll->size * sizeof(coll->entry[0]);
for(i = 0; i < coll->entries; i++) {
struct ncnf_obj_s *child=coll->entry[i].object;
if(flatten_type
&& *flatten_type != '-'
&& *flatten_type != '*'
&& strcmp(flatten_type, child->type)
) continue;
_ncnf_obj_dump_recursive(f, child, 0,
marked_only,
verbose,
indent + (obj->type?indent_shift:0),
indent_shift, flatten_type ? 1 : 0,
&recursive_size);
}
/* Put some space between entries */
if(obj->m_collection[cc].entries
&& obj->m_collection[cc + 1].entries
&& !flatten_type)
fprintf(f, "\n");
}
default:
/* Do nothing */
break;
}
if(obj->obj_class == NOBJ_COMPLEX && !flatten_type && !single_level) {
_print_indent(f, indent);
fputs("}", f);
if(verbose) {
fprintf(f, " # %s \"%s\" RSIZE=%d",
obj->type, obj->value,
recursive_size
);
}
fputs(indent?"\n":"\n\n", f);
}
if(ret_rsize) *ret_rsize += recursive_size;
}
syntax highlighted by Code2HTML, v. 0.9.1