<commit_before>#include <assert.h>
#include <vector>
#include <string>
#include <unordered_set>

#include "zproto.hpp"
#include "header.h"

static std::unordered_set<struct zproto_struct *> protocol;
static std::unordered_set<struct zproto_struct *> defined;

struct prototype_args {
	int level;
	int hasmap = 0;
	std::vector<std::string> type;
	std::vector<std::string> fields;
	std::vector<std::string> encode;
};

const char *funcproto = "\
%sprotected:\n\
%svirtual int _encode_field(struct zproto_args *args) const;\n\
%svirtual int _decode_field(struct zproto_args *args);\n\
%s\
%spublic:\n\
%svirtual const char *_name() const;\n\
";

static std::string
tab(int level)
{
	std::string str;
	level *= 8;
	str.reserve(level);
	for (int i = 0; i < level; i++)
		str += " ";
	return str;
}

static int prototype_cb(struct zproto_args *args);

static void
formatst(struct zproto_struct *st, struct prototype_args &newargs)
{
	std::string t1 = tab(newargs.level);
	std::string t2 = tab(newargs.level - 1);
	std::string mapbuf;
	char buff[2048];

	zproto_travel(st, prototype_cb, &newargs);
	//subtype
	newargs.fields.insert(
		newargs.fields.begin(),
		newargs.type.begin(),
		newargs.type.end()
	);
	//open
	const char *herit;
	if (protocol.count(st))
		herit = ":public wirep ";
	else
		herit = ":public wire ";
	newargs.fields.insert(
		newargs.fields.begin(),
                t2 + "struct " + zproto_name(st) + herit + "{\n");
	if (newargs.hasmap)
		mapbuf = t1 + "mutable std::vector<const void *>maptoarray;\n";
	//member function
        snprintf(buff, 2048, funcproto,
			t2.c_str(),
			t1.c_str(), t1.c_str(),
			mapbuf.c_str(),
			t2.c_str(),
			t1.c_str());
	newargs.fields.push_back(buff);

	//close
	newargs.fields.insert(
		newargs.fields.end(),
		t2 + "};\n"
		);
	defined.insert(st);
	return ;
}

struct find_field_ud {
	int tag;
	std::string type;
};

static int
find_field_type(struct zproto_args *args)
{
	struct find_field_ud *ud = (struct find_field_ud *)args->ud;
	if (ud->tag == args->tag) {
		switch (args->type) {
		case ZPROTO_STRING:
			ud->type = "std::string";
			break;
		case ZPROTO_BOOLEAN:
			ud->type = "uint8_t";
			break;
		case ZPROTO_INTEGER:
			ud->type = "uint32_t";
			break;
		case ZPROTO_FLOAT:
			ud->type = "float";
			break;
		default:
			assert(!"unsupport key type of std::map");
			break;
		}
	}
	return 0;
}

static int
prototype_cb(struct zproto_args *args)
{
	struct prototype_args *ud = (struct prototype_args *)args->ud;
	struct prototype_args newargs;
	char buff[2048];
	std::string type;
	std::string subtype;

	if (args->maptag) {
		std::string str;
		assert(args->idx >= 0);
		struct find_field_ud fud;
		fud.tag = args->maptag;
		zproto_travel(args->sttype, find_field_type, &fud);
		assert(fud.type != "");
		str = "std::unordered_map<" + fud.type + ", %s> %s;\n";
		type = tab(ud->level) + str;
		ud->hasmap = 1;
	} else if(args->idx >= 0) {
		type = tab(ud->level) + "std::vector<%s> %s;\n";
	} else {
		type = tab(ud->level) + "%s %s;\n";
	}

	switch (args->type) {
	case ZPROTO_STRUCT:
		if (protocol.count(args->sttype) == 0 && defined.count(args->sttype) == 0) { //protocol define
			newargs.level = ud->level + 1;
			formatst(args->sttype, newargs);
			ud->type.insert(ud->type.end(), newargs.fields.begin(), newargs.fields.end());
		}
		subtype = std::string("struct ") + zproto_name(args->sttype);
		break;
	case ZPROTO_STRING:
		subtype = "std::string";
		break;
	case ZPROTO_BOOLEAN:
		subtype = "bool";
		break;
	case ZPROTO_INTEGER:
		subtype = "uint32_t";
		break;
	case ZPROTO_FLOAT:
		subtype = "float";
		break;
	default:
		break;
	}
	snprintf(buff, 2048, type.c_str(), subtype.c_str(),args->name);
	type = buff;
	ud->fields.push_back(type);
	return 0;
}

static void
dump_vecstring(FILE *fp, const std::vector<std::string> &tbl)
{
	for (const auto &str:tbl)
		fprintf(fp, "%s", str.c_str());
	return;
}

static void
dumpst(FILE *fp, struct zproto *z, struct zproto_struct *st)
{
	struct prototype_args args;<commit_msg>cpp add default value<commit_after>#include <assert.h>
#include <vector>
#include <string>
#include <unordered_set>

#include "zproto.hpp"
#include "header.h"

static std::unordered_set<struct zproto_struct *> protocol;
static std::unordered_set<struct zproto_struct *> defined;

struct prototype_args {
	int level;
	int hasmap = 0;
	std::vector<std::string> type;
	std::vector<std::string> fields;
	std::vector<std::string> encode;
};

const char *funcproto = "\
%sprotected:\n\
%svirtual int _encode_field(struct zproto_args *args) const;\n\
%svirtual int _decode_field(struct zproto_args *args);\n\
%s\
%spublic:\n\
%svirtual const char *_name() const;\n\
";

static std::string
tab(int level)
{
	std::string str;
	level *= 8;
	str.reserve(level);
	for (int i = 0; i < level; i++)
		str += " ";
	return str;
}

static int prototype_cb(struct zproto_args *args);

static void
formatst(struct zproto_struct *st, struct prototype_args &newargs)
{
	std::string t1 = tab(newargs.level);
	std::string t2 = tab(newargs.level - 1);
	std::string mapbuf;
	char buff[2048];

	zproto_travel(st, prototype_cb, &newargs);
	//subtype
	newargs.fields.insert(
		newargs.fields.begin(),
		newargs.type.begin(),
		newargs.type.end()
	);
	//open
	const char *herit;
	if (protocol.count(st))
		herit = ":public wirep ";
	else
		herit = ":public wire ";
	newargs.fields.insert(
		newargs.fields.begin(),
                t2 + "struct " + zproto_name(st) + herit + "{\n");
	if (newargs.hasmap)
		mapbuf = t1 + "mutable std::vector<const void *>maptoarray;\n";
	//member function
        snprintf(buff, 2048, funcproto,
			t2.c_str(),
			t1.c_str(), t1.c_str(),
			mapbuf.c_str(),
			t2.c_str(),
			t1.c_str());
	newargs.fields.push_back(buff);

	//close
	newargs.fields.insert(
		newargs.fields.end(),
		t2 + "};\n"
		);
	defined.insert(st);
	return ;
}

struct find_field_ud {
	int tag;
	std::string type;
};

static int
find_field_type(struct zproto_args *args)
{
	struct find_field_ud *ud = (struct find_field_ud *)args->ud;
	if (ud->tag == args->tag) {
		switch (args->type) {
		case ZPROTO_STRING:
			ud->type = "std::string";
			break;
		case ZPROTO_BOOLEAN:
			ud->type = "uint8_t";
			break;
		case ZPROTO_INTEGER:
			ud->type = "uint32_t";
			break;
		case ZPROTO_FLOAT:
			ud->type = "float";
			break;
		default:
			assert(!"unsupport key type of std::map");
			break;
		}
	}
	return 0;
}

static int
prototype_cb(struct zproto_args *args)
{
	struct prototype_args *ud = (struct prototype_args *)args->ud;
	struct prototype_args newargs;
	char buff[2048];
	std::string type;
	std::string subtype;
	std::string defval;
	if (args->maptag) {
		std::string str;
		assert(args->idx >= 0);
		struct find_field_ud fud;
		fud.tag = args->maptag;
		zproto_travel(args->sttype, find_field_type, &fud);
		assert(fud.type != "");
		str = "std::unordered_map<" + fud.type + ", %s> %s%s;\n";
		type = tab(ud->level) + str;
		ud->hasmap = 1;
	} else if(args->idx >= 0) {
		type = tab(ud->level) + "std::vector<%s> %s%s;\n";
	} else {
		type = tab(ud->level) + "%s %s%s;\n";
		switch (args->type) {
		case ZPROTO_BOOLEAN:
			defval = " = false";
			break;
		case ZPROTO_INTEGER:
			defval = " = 0";
			break;
		case ZPROTO_FLOAT:
			defval = " = 0.0f";
			break;
		}
	}

	switch (args->type) {
	case ZPROTO_STRUCT:
		if (protocol.count(args->sttype) == 0 && defined.count(args->sttype) == 0) { //protocol define
			newargs.level = ud->level + 1;
			formatst(args->sttype, newargs);
			ud->type.insert(ud->type.end(), newargs.fields.begin(), newargs.fields.end());
		}
		subtype = std::string("struct ") + zproto_name(args->sttype);
		break;
	case ZPROTO_STRING:
		subtype = "std::string";
		break;
	case ZPROTO_BOOLEAN:
		subtype = "bool";
		break;
	case ZPROTO_INTEGER:
		subtype = "uint32_t";
		break;
	case ZPROTO_FLOAT:
		subtype = "float";
		break;
	default:
		break;
	}
	snprintf(buff, 2048, type.c_str(), subtype.c_str(),args->name, defval.c_str());
	type = buff;
	ud->fields.push_back(type);
	return 0;
}

static void
dump_vecstring(FILE *fp, const std::vector<std::string> &tbl)
{
	for (const auto &str:tbl)
		fprintf(fp, "%s", str.c_str());
	return;
}

static void
dumpst(FILE *fp, struct zproto *z, struct zproto_struct *st)
{
	struct prototype_args args;
{'fraction_non_alphanumeric': 0.16994416120417577, 'fraction_numerical': 0.010803593105122602, 'mean_word_length': 4.048406862745098, 'pattern_counts': {'":': 4, '<': 31, '<?xml version=': 0, '>': 90, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4501532', 'n_tokens_mistral': 3478, 'n_tokens_neox': 3239, 'n_words': 708}