char* pretty_print_any(TreeNode* node, int dd) { int64_t vv_i; double vv_d; switch (node->type) { case INTEGER_TYPE: vv_i = *((int64_t*)node->data); return lsprintf("%ld", vv_i); case FLOAT_TYPE: vv_d = *((double*)node->data); return lsprintf("%f", vv_d); case SYMBOL_TYPE: return (char*)node->data; case STRING_TYPE: return pretty_print_string(node, dd); case BINOP_TYPE: return pretty_print_binop(node, dd); case UNOP_TYPE: return pretty_print_unop(node, dd); case DOT_TYPE: return pretty_print_dot(node, dd); case BIND_TYPE: return pretty_print_bind(node, dd); case LIST_TYPE: return pretty_print_list(node, dd); case FUN_TYPE: return pretty_print_fun(node, dd); case LAMBDA_TYPE: return pretty_print_lambda(node, dd); case CALL_TYPE: return pretty_print_call(node, dd); case CALL_LAMBDA_TYPE: return pretty_print_call_lambda(node, dd); default: carp("pretty_print_tree(): Bad node type."); } abort(); }
/* * Format the specified option so that a human can easily read it. */ char * pretty_print_option(unsigned int code, struct option_data *option, int emit_punct) { static char optbuf[32768]; /* XXX */ int hunksize = 0, numhunk = -1, numelem = 0; char fmtbuf[32], *op = optbuf; int i, j, k, opleft = sizeof(optbuf); unsigned char *data = option->data; unsigned char *dp = data; int len = option->len; int opcount = 0; struct in_addr foo; char comma; memset(optbuf, 0, sizeof(optbuf)); /* Code should be between 0 and 255. */ if (code > 255) { warning("pretty_print_option: bad code %d", code); goto done; } if (emit_punct) comma = ','; else comma = ' '; /* Figure out the size of the data. */ for (i = 0; dhcp_options[code].format[i]; i++) { if (!numhunk) { warning("%s: Excess information in format string: %s", dhcp_options[code].name, &(dhcp_options[code].format[i])); goto done; } numelem++; fmtbuf[i] = dhcp_options[code].format[i]; switch (dhcp_options[code].format[i]) { case 'A': --numelem; fmtbuf[i] = 0; numhunk = 0; if (hunksize == 0) { warning("%s: no size indicator before A" " in format string: %s", dhcp_options[code].name, dhcp_options[code].format); goto done; } break; case 'X': for (k = 0; k < len; k++) if (!isascii(data[k]) || !isprint(data[k])) break; if (k == len) { fmtbuf[i] = 't'; numhunk = -2; } else { hunksize++; comma = ':'; numhunk = 0; } fmtbuf[i + 1] = 0; break; case 't': fmtbuf[i + 1] = 0; numhunk = -2; break; case 'I': case 'l': case 'L': hunksize += 4; break; case 'S': hunksize += 2; break; case 'B': case 'f': hunksize++; break; case 'e': break; case 'C': hunksize += 5; break; default: warning("%s: garbage in format string: %s", dhcp_options[code].name, &(dhcp_options[code].format[i])); goto done; } } /* Check for too few bytes. */ if (hunksize > len) { warning("%s: expecting at least %d bytes; got %d", dhcp_options[code].name, hunksize, len); goto done; } /* Check for too many bytes. */ if (numhunk == -1 && hunksize < len) { warning("%s: expecting only %d bytes: got %d", dhcp_options[code].name, hunksize, len); goto done; } /* If this is an array, compute its size. */ if (!numhunk) numhunk = len / hunksize; /* See if we got an exact number of hunks. */ if (numhunk > 0 && numhunk * hunksize != len) { warning("%s: expecting %d bytes: got %d", dhcp_options[code].name, numhunk * hunksize, len); goto done; } /* A one-hunk array prints the same as a single hunk. */ if (numhunk < 0) numhunk = 1; /* Cycle through the array (or hunk) printing the data. */ for (i = 0; i < numhunk; i++) { for (j = 0; j < numelem; j++) { switch (fmtbuf[j]) { case 't': opcount = pretty_print_string(op, opleft, dp, len, emit_punct); break; case 'I': foo.s_addr = htonl(getULong(dp)); opcount = snprintf(op, opleft, "%s", inet_ntoa(foo)); dp += 4; break; case 'l': opcount = snprintf(op, opleft, "%ld", (long)getLong(dp)); dp += 4; break; case 'L': opcount = snprintf(op, opleft, "%lu", (unsigned long)getULong(dp)); dp += 4; break; case 'S': opcount = snprintf(op, opleft, "%u", getUShort(dp)); dp += 2; break; case 'B': opcount = snprintf(op, opleft, "%u", *dp); dp++; break; case 'X': opcount = snprintf(op, opleft, "%x", *dp); dp++; break; case 'f': opcount = snprintf(op, opleft, "%s", *dp ? "true" : "false"); dp++; break; case 'C': memset(&foo, 0, sizeof(foo)); memcpy(&foo.s_addr, dp+1, (*dp + 7) / 8); opcount = snprintf(op, opleft, "%s/%u", inet_ntoa(foo), *dp); if (opcount >= opleft || opcount == -1) goto toobig; dp += 1 + (*dp + 7) / 8; break; default: warning("Unexpected format code %c", fmtbuf[j]); goto toobig; } if (opcount >= opleft || opcount == -1) goto toobig; opleft -= opcount; op += opcount; if (j + 1 < numelem && comma != ':') { opcount = snprintf(op, opleft, " "); if (opcount >= opleft || opcount == -1) goto toobig; opleft -= opcount; op += opcount; } } if (i + 1 < numhunk) { opcount = snprintf(op, opleft, "%c", comma); if (opcount >= opleft || opcount == -1) goto toobig; opleft -= opcount; op += opcount; } } done: return (optbuf); toobig: memset(optbuf, 0, sizeof(optbuf)); return (optbuf); }
void pretty_print(lexeme tree) { if (tree == NULL) { //fprintf(stderr, "Got empty tree. Returning...\n"); return; } lexeme_type type = lexeme_get_type(tree); switch(type) { case PAIR: pretty_print_pair(tree); break; case STRING: pretty_print_string(tree); break; case AMP: pretty_print_amp(tree); break; case DOT: pretty_print_dot(tree); break; case RETURN: pretty_print_return(tree); break; case BLOCK: pretty_print_block(tree); break; case UNITLIST: pretty_print_unitlist(tree); break; case INT: pretty_print_int(tree); break; case DEC: pretty_print_dec(tree); break; case TRUE: pretty_print_true(tree); break; case FALSE: pretty_print_false(tree); break; case NIL: pretty_print_nil(tree); break; case ID: pretty_print_id(tree); break; case BIND: pretty_print_bind(tree); break; case LAMBDA: pretty_print_lambda(tree); break; case PARAMLIST: pretty_print_paramlist(tree); break; case CALL: pretty_print_call(tree); break; case ARGLIST: pretty_print_arglist(tree); break; default: printf("BAD LEXEME"); lexeme_destroy(tree); break; } }