Exemple #1
0
void save_topology(char *filenm)
{
    extern void	print_ethernets(FILE *fp);

    NODE	*np;
    int		n;

    if(filenm == (char *)NULL || *filenm == '\0')
	topfp	= stdout;
    else
	if((topfp = fopen(filenm, "w")) == (FILE *)NULL) {
	    fprintf(stderr,"%s: cannot create %s\n", argv0,filenm);
	    return;
	}

/*  FIRSTLY, PRINT THE DEFAULT NODE AND LINK ATTRIBUTES */
    print_node_attr(TRUE, &DEFAULTNODE, "");
    print_link_attr(TRUE, (LINKATTR *)chararray, &DEFAULTLINK, FALSE);
    fprintf(topfp,"\n");

/*  NEXT, PRINT ANY GLOBAL ATTRIBUTES THAT HAVE BEEN DEFINED */
    if(gattr.bgimage)
	fprintf(topfp,"bgimage = \"%s\"\n", gattr.bgimage);
    if(gattr.drawframes)
	fprintf(topfp,"drawframes = true\n");
    if(gattr.trace_filenm)
	fprintf(topfp,"tracefile = \"%s\"\n", gattr.trace_filenm);
    if(gattr.showcostperframe)
	fprintf(topfp,"showcostperframe = true\n");
    else if(gattr.showcostperbyte)
	fprintf(topfp,"showcostperbyte = true\n");
    fprintf(topfp,"\n");

/*  NEXT, PRINT ANY ETHERNET SEGMENTS THAT WE HAVE */
    print_ethernets(topfp);

/*  FINALLY, FOR EACH NODE, PRINT ITS LOCAL NODE AND LINK INFORMATION */
    for(n=0, np=NP ; n<_NNODES ; n++, np++) {
	fprintf(topfp,"%s %s {\n",
		np->nodetype == NT_HOST ? "host" : "router", np->nodename);
	fprintf(topfp,"    x=%d, y=%d\n", np->nattr.x,np->nattr.y);
	if(np->nattr.osname != (char *)NULL)
	    fprintf(topfp,"    osname = \"%s\"\n", np->nattr.osname);

	print_node_attr(FALSE, &(np->nattr), "    ");
	print_link_attr(FALSE, &DEFAULTLINK, &(np->lattr), FALSE);
	print_links(n, np->nlinks, np->links);
	fprintf(topfp,"}\n");
    }
    if(topfp != stdout)
	fclose(topfp);
}
Exemple #2
0
void			print_result(t_env *env, int i, int after)
{
	if (!env->info)
		return ;
	if (!after)
		tt_psss(RED, "\nCurrent data :\n", BLUE);
	else
		tt_psss(RED, "\nAfter solving :\n", BLUE);
	tt_psns("Ants: ", env->nb_ants, "\n");
	while (env->nodes && i < env->nb_nodes)
	{
		tt_psss(GRN, "name : ", env->nodes[i]->name);
		tt_pssn(MAG, "\t START: ", env->nodes[i]->isbegin);
		tt_psn(" | END: ", env->nodes[i]->isend);
		tt_psn(" | weight: ", env->nodes[i]->weight_end);
		tt_psn(" | ants: ", env->nodes[i]->ant_count);
		tt_pssn(CYAN, "\t coord x,y: (", env->nodes[i]->coord.x);
		tt_psn(", ", env->nodes[i]->coord.y);
		tt_ps(")\n");
		i++;
	}
	if (after)
		print_links(env->nodes, env->nb_nodes);
}
Exemple #3
0
void print_list_books()         /* 메뉴 2번인 도서목록 출력을 구현. */
{
    print_links(main_list);
    return;
}
Exemple #4
0
static void
print_vp(int nspec)
{
	struct pchip *chip;
	struct core *core;
	struct vcpu *vcpu;
	struct link *l1, *l2;
	int len;
	for (l1 = pchips; l1; l1 = l1->l_next) {

		chip = l1->l_ptr;

		if ((nspec != 0) && (chip->p_doit == 0))
			continue;

		vcpu = chip->p_vcpus->l_ptr;

		/*
		 * Note that some of the way these strings are broken up are
		 * to accommodate the legacy translations so that we won't
		 * have to retranslate for this utility.
		 */
		if ((chip->p_ncore == 1) || (chip->p_ncore == chip->p_nvcpu)) {
			(void) printf(_("%s has %d virtual %s"),
			    _("The physical processor"),
			    chip->p_nvcpu,
			    chip->p_nvcpu > 1 ?
			    _("processors") :
			    _("processor"));
		} else {
			(void) printf(_("%s has %d %s and %d virtual %s"),
			    _("The physical processor"),
			    chip->p_ncore, _("cores"),
			    chip->p_nvcpu,
			    chip->p_nvcpu > 1 ?
			    _("processors") : _("processor"));
		}

		print_links(chip->p_vcpus);
		(void) putchar('\n');

		if ((chip->p_ncore == 1) || (chip->p_ncore == chip->p_nvcpu)) {
			if (strlen(vcpu->v_impl)) {
				(void) printf("  %s\n", vcpu->v_impl);
			}
			if (((len = strlen(vcpu->v_brand)) != 0) &&
			    (strncmp(vcpu->v_brand, vcpu->v_impl, len) != 0))
				(void) printf("\t%s", vcpu->v_brand);
			if (strcmp(vcpu->v_socket, "Unknown") != 0)
				(void) printf("\t[ %s: %s ]", _("Socket"),
				    vcpu->v_socket);
			(void) putchar('\n');
		} else {
			for (l2 = chip->p_cores; l2; l2 = l2->l_next) {
				core = l2->l_ptr;
				(void) printf(_("  %s has %d virtual %s"),
				    _("The core"),
				    core->c_nvcpu,
				    chip->p_nvcpu > 1 ?
				    _("processors") : _("processor"));
				print_links(core->c_vcpus);
				(void) putchar('\n');
			}
			if (strlen(vcpu->v_impl)) {
				(void) printf("    %s\n", vcpu->v_impl);
			}
			if (((len = strlen(vcpu->v_brand)) != 0) &&
			    (strncmp(vcpu->v_brand, vcpu->v_impl, len) != 0))
				(void) printf("      %s\n", vcpu->v_brand);
		}
	}
}
Exemple #5
0
static enumError Generate ( control_t * ctrl )
{
    ASSERT(ctrl);
    ASSERT(ctrl->info);

    FILE * cf = ctrl->cf;
    FILE * hf = ctrl->hf;
    ASSERT(cf);
    ASSERT(hf);

    FREE(ctrl->opt_allow_grp);
    FREE(ctrl->opt_allow_cmd);
    ctrl->opt_allow_grp = ctrl->opt_allow_cmd = 0;

    const info_t *info;


    //----- ui header

    fprintf(cf,text_ui_head);
    fprintf(hf,text_ui_head);


    //----- setup guard

    char guard[100];
    snprintf(guard,sizeof(guard),"WIT_UI_%s_h",ctrl->info->c_name);
    char * ptr;
    for ( ptr = guard; *ptr; ptr++ )
	*ptr = *ptr == '-' ? '_' : toupper((int)*ptr);
    fprintf(hf,"\n#ifndef %s\n#define %s\n",guard,guard);


    //----- header

    ASSERT( ctrl->info->type & T_DEF_TOOL );
    ccp tool_name = ctrl->info->c_name;

    fprintf(cf,"#include <getopt.h>\n");
    fprintf(cf,"#include \"ui-%s.h\"\n",tool_name);

    fprintf(hf,"#include \"lib-std.h\"\n");
    fprintf(hf,"#include \"ui.h\"\n");


    //----- print enum enumOptions & OptionInfo[]

    print_section(cf,sep1,"OptionInfo[]");
    print_section(hf,sep1,"enum enumOptions");

    char * var_ptr = var_buf;
    char * var_end = var_buf + sizeof(var_buf);
    var_ptr += snprintf(var_ptr,var_end-var_ptr,
		"extern const InfoOption_t OptionInfo[OPT__N_TOTAL+1];\n");

    fprintf(cf,
	    "const InfoOption_t OptionInfo[OPT__N_TOTAL+1] =\n"
	    "{\n"
	    "    {0,0,0,0,0}, // OPT_NONE,\n"
	    "\n"
	    );

    fprintf(hf,
	    "typedef enum enumOptions\n"
	    "{\n"
	    "\tOPT_NONE,\n"
	    "\n"
	    );

    ctrl->n_opt = 1;
    ctrl->n_opt_specific = 0;
    if ( ctrl->n_cmd )
    {
	fprintf(cf,"    //----- command specific options -----\n\n");
	fprintf(hf,"\t//----- command specific options -----\n\n");

	for ( info = ctrl->info; info < ctrl->end; info++ )
	    if ( info->type & F_OPT_COMMAND )
		print_opt(ctrl,info);

	ctrl->n_opt_specific = ctrl->n_opt;

	fprintf(cf,
		"    {0,0,0,0,0}, // OPT__N_SPECIFIC == %d\n\n"
		"    //----- global options -----\n\n",
		ctrl->n_opt_specific );

	fprintf(hf,
		"\n\tOPT__N_SPECIFIC, // == %d \n\n"
		"\t//----- global options -----\n\n",
		ctrl->n_opt_specific );
    }

    for ( info = ctrl->info; info < ctrl->end; info++ )
	if ( info->type & F_OPT_GLOBAL )
	    print_opt(ctrl,info);

    fprintf(cf,
	    "    {0,0,0,0,0} // OPT__N_TOTAL == %d\n\n"
	    "};\n"
	    ,ctrl->n_opt );

    fprintf(hf,
	    "\n\tOPT__N_TOTAL // == %d\n\n"
	    "} enumOptions;\n"
	    ,ctrl->n_opt );

    if (ctrl->n_opt_specific)
    {
	noTRACE("opt_allowed = ( %2u + %2u ) * %2u\n",
		ctrl->n_grp, ctrl->n_cmd, ctrl->n_opt_specific );
	if (ctrl->n_grp)
	    ctrl->opt_allow_grp = CALLOC(ctrl->n_grp,ctrl->n_opt_specific);
	ctrl->opt_allow_cmd = CALLOC(ctrl->n_cmd,ctrl->n_opt_specific);
    }


    //----- print alternate option infos

    bool done = false;
    const info_t * last_cmd = ctrl->info;
    ctrl->opt_prefix = "def";
    for ( info = ctrl->info; info < ctrl->end; info++ )
    {
	if ( info->type & T_CMD_BEG )
	{
	    ctrl->opt_prefix = "cmd";
	    last_cmd = info;
	}
	else if ( info->type & T_GRP_BEG )
	{
	    ctrl->opt_prefix = "grp";
	    last_cmd = info;
	}
	else if ( info->type & T_CMD_OPT && info->help && *info->help )
	{
	    if (!done)
	    {
		print_section(cf,sep1,"alternate option infos");
		done = true;
	    }

	    const info_t * info0;
	    for ( info0 = ctrl->info; info0 < info; info0++ )
		if ( info0->type & T_DEF_OPT && !strcmp(info->c_name,info0->c_name) )
		{
		    print_info_opt(ctrl,info,info0,last_cmd->c_name);
		    break;
		}
	}
    }

    //----- print enum enumOptionsBit

    if ( ctrl->n_cmd )
    {
	print_section(hf,sep1,"enum enumOptionsBit");

	fprintf(hf,
		"//\t*****  only for verification  *****\n"
		"\n"
		"//typedef enum enumOptionsBit\n"
		"//{\n"
		"//\t//----- command specific options -----\n"
		"//\n"
		);

	for ( info = ctrl->info; info < ctrl->end; info++ )
	    if ( info->type & F_OPT_COMMAND )
		fprintf(hf,"//\tOB_%s%.*s= 1llu << OPT_%s,\n",
			info->c_name,
			( 28 - (int)strlen(info->c_name) ) / 8, tabs,
			info->c_name );

	fprintf(hf,"//\n//\t//----- group & command options -----\n");

	for ( info = ctrl->info; info < ctrl->end; )
	{
	    ccp cmd_name;
	    u8 * opt_allow = 0;
	    if ( info->type & T_CMD_BEG )
	    {
		cmd_name = info->c_name;
		fprintf(hf,"//\n//\tOB_CMD_%s%.*s=",
			info->c_name,
			( 24 - (int)strlen(info->c_name) ) / 8, tabs );
		if (ctrl->opt_allow_cmd)
		{
		    //PRINT("SELECT ALLOW CMD %u/%s\n",info->index,info->c_name);
		    opt_allow = ctrl->opt_allow_cmd + info->index * ctrl->n_opt_specific;
		}
	    }
	    else if ( info->type & T_GRP_BEG )
	    {
		cmd_name = info->c_name;
		fprintf(hf,"//\n//\tOB_GRP_%s%.*s=",
			info->c_name,
			( 24 - (int)strlen(info->c_name) ) / 8, tabs );
		if (ctrl->opt_allow_grp)
		{
		    //PRINT("SELECT ALLOW GRP %u/%s\n",info->index,info->c_name);
		    opt_allow = ctrl->opt_allow_grp + info->index * ctrl->n_opt_specific;
		}
	    }
	    else
	    {
		info++;
		continue;
	    }

	    info++;
	    char * dest = iobuf;
	    while ( info < ctrl->end )
	    {
		if ( info->type & T_ALL_OPT )
		{
		    dest += sprintf(dest,"\n//\t\t\t\t| ~(u64)0");
		    if (opt_allow)
		    {
			//PRINT("ALLOW ALL\n");
			memset(opt_allow,1,ctrl->n_opt_specific);
		    }
		}
		else if ( info->type & T_COPY_CMD )
		{
		    dest += sprintf(dest,"\n//\t\t\t\t| OB_CMD_%s",info->c_name);
		    if (opt_allow)
		    {
			//PRINT("OR CMD %u/%s\n",info->index,info->c_name);
			DASSERT(ctrl->opt_allow_cmd);
			u8 * src = ctrl->opt_allow_cmd + info->index * ctrl->n_opt_specific;
			u8 * dest = opt_allow;
			int count = ctrl->n_opt_specific;
			while ( count-- > 0 )
			    *dest++ |= *src++;
		    }
		}
		else if ( info->type & T_COPY_GRP )
		{
		    dest += sprintf(dest,"\n//\t\t\t\t| OB_GRP_%s",info->c_name);
		    if ( opt_allow && ctrl->opt_allow_grp )
		    {
			//PRINT("OR GRP %u/%s\n",info->index,info->c_name);
			u8 * src = ctrl->opt_allow_grp + info->index * ctrl->n_opt_specific;
			u8 * dest = opt_allow;
			int count = ctrl->n_opt_specific;
			while ( count-- > 0 )
			    *dest++ |= *src++;
		    }
		}
		else if ( info->type & T_CMD_OPT )
		{
		    if (FindStringField(&ctrl->copt,info->c_name))
		    {
			dest += sprintf(dest,"\n//\t\t\t\t| OB_%s",info->c_name);
			if ( opt_allow && info->index )
			{
			    //PRINT("ALLOW OPT %u/%s\n",info->index,info->c_name);
			    opt_allow[info->index] = 1;
			}
		    }
		    else if (!FindStringField(&ctrl->gopt,info->c_name))
			ERROR0(ERR_SEMANTIC,"Option not defined: %s %s --%s",
				tool_name, cmd_name, info->c_name );
		}
		else if ( info->type & (T_CMD_BEG|T_GRP_BEG) )
		    break;
		ASSERT( dest < iobuf + sizeof(iobuf) );
		info++;
	    }
	    if ( dest == iobuf )
		fprintf(hf," 0,\n");
	    else
		fprintf(hf,"%s,\n",iobuf+8);
	}

	fprintf(hf,"//\n//} enumOptionsBit;\n");
    }


    //----- print enum enumCommands & CommandTab[]

    print_section(hf,sep1,"enum enumCommands");
    fprintf(hf,
	    "typedef enum enumCommands\n"
	    "{\n"
	    "\tCMD__NONE,"
	    );

    if ( ctrl->n_cmd )
    {
	print_section(cf,sep1,"CommandTab[]");
	fputs("\n\n",hf);

	var_ptr += snprintf(var_ptr,var_end-var_ptr,
		"extern const CommandTab_t CommandTab[];\n");

	fprintf(cf,
		"const CommandTab_t CommandTab[] =\n"
		"{\n"
		);

	for ( info = ctrl->info; info < ctrl->end; info++ )
	    if ( info->type & T_DEF_CMD )
	    {
		fprintf( hf, "\tCMD_%s,\n",info->c_name);
		ccp ptr = info->namelist;
		while (*ptr)
		{
		    ccp n1 = ptr;
		    while ( *ptr && *ptr != '|' )
			ptr++;
		    const int l1 = ptr - n1;
		    while ( *ptr == '|' )
			ptr++;
		    if (*ptr)
		    {
			ccp n2 = ptr;
			while ( *ptr && *ptr != '|' )
			    ptr++;
			const int l2 = ptr - n2;

			fprintf(cf,
				"    { CMD_%s,%.*s\"%.*s\",%.*s\"%.*s\",%.*s0 },\n",
				info->c_name, (20-(int)strlen(info->c_name))/8, tabs,
				l1, n1, (20-l1)/8, tabs,
				l2, n2, (20-l2)/8, tabs );

			while ( *ptr == '|' )
			    ptr++;
		    }
		    else
			fprintf(cf, "    { CMD_%s,%.*s\"%.*s\",%.*s0,\t\t0 },\n",
				info->c_name, (20-(int)strlen(info->c_name))/8, tabs,
				l1, n1, (20-l1)/8, tabs );
		}
	    }
	    else if ( info->type == T_SEP_CMD )
		fprintf(hf,"\n");

	fprintf(cf,
		"\n    { CMD__N,0,0,0 }\n"
		"};\n"
		);
    }

    fprintf(hf,
	    "\n\tCMD__N // == %u\n\n"
	    "} enumCommands;\n"
	    , ctrl->n_cmd );


    //----- print options

    print_section(cf,sep1,"OptionShort & OptionLong");

    char * dest = iobuf;
    for ( info = ctrl->info; info < ctrl->end; info++ )
	if ( info->type & T_DEF_OPT && info->namelist[1] == '|' )
	{
	    *dest++ = info->namelist[0];
	    if ( info->type & F_OPT_OPTPARAM )
		*dest++ = ':';
	    if ( info->type & (F_OPT_OPTPARAM|F_OPT_PARAM) )
		*dest++ = ':';
	}
    *dest = 0;
    fprintf(cf,"const char OptionShort[] = \"%s\";\n\n",iobuf);
    var_ptr += snprintf(var_ptr,var_end-var_ptr,
		"extern const char OptionShort[];\n");

    ccp opt_buf[OPT_INDEX_SIZE];
    memset(opt_buf,0,sizeof(opt_buf));
    int getopt_idx = OPT_LONG_BASE;

    fprintf(cf,"const struct option OptionLong[] =\n{\n");
    var_ptr += snprintf(var_ptr,var_end-var_ptr,
		"extern const struct option OptionLong[];\n");

    for ( info = ctrl->info; info < ctrl->end; info++ )
	if ( info->type & T_DEF_OPT )
	{
	    ccp ptr = info->namelist;
	    const int pmode = (info->type & F_OPT_OPTPARAM)
				? 2
				: (info->type & F_OPT_PARAM)
					? 1
					: 0;

	    if ( info->namelist[1] == '|' )
	    {
		snprintf(iobuf,sizeof(iobuf),"%d, 0, '%c'",
			pmode, info->namelist[0] );
		ptr += 2;
		opt_buf[(u8)(info->namelist[0])] = info->c_name;
	    }
	    else
	    {
		snprintf(iobuf,sizeof(iobuf),"%d, 0, GO_%s",
			pmode, info->c_name );
		ASSERT_MSG( getopt_idx < OPT_INDEX_SIZE,
				"getopt_idx[%x] >= OPT_INDEX_SIZE[%x]\n",
				getopt_idx, OPT_INDEX_SIZE );
		opt_buf[(u8)(getopt_idx++)] = info->c_name;
	    }

	    int indent = 0;
	    while (*ptr)
	    {
		ccp start = ptr;
		while ( *ptr && *ptr != '|' )
		    ptr++;
		const int len = ptr - start;
		fprintf(cf,"\t%s{ \"%.*s\",%.*s%s },\n",
			indent ? " " : "", len, start, (26-len-indent)/8, tabs, iobuf );
		if (*ptr)
		    ptr++;
		indent = 1;
	    }
	}
    fprintf(cf,"\n\t{0,0,0,0}\n};\n");
    

    //----- print enumGetOpt

    print_section(hf,sep1,"enumGetOpt");
    fprintf(hf,"typedef enum enumGetOpt\n{");

    // add '?' temporary;
    ASSERT(!opt_buf['?']);
    opt_buf['?'] = "_ERR";
    
    static const int septab[] = { 0, '0', '9'+1, '?', '?'+1,
				  'A', 'Z'+1, 'a', 'z'+1,
				  OPT_LONG_BASE, OPT_INDEX_SIZE };
    const int * sepptr = septab;
    int i;
    for ( i = 0; i < OPT_INDEX_SIZE; i++ )
	if ( opt_buf[i] )
	{
	    if ( i >= *sepptr )
	    {
		fputc('\n',hf);
		while ( i >= *sepptr )
		    sepptr++;
	    }
	    if ( i < OPT_LONG_BASE )
		fprintf(hf,"\tGO_%s%.*s= '%c',\n",
			opt_buf[i], (28-(int)strlen(opt_buf[i]))/8, tabs, i );
	    else if ( i == OPT_LONG_BASE )
		fprintf(hf,"\tGO_%s%.*s= 0x%02x,\n",
			opt_buf[i], (28-(int)strlen(opt_buf[i]))/8, tabs, i );
	    else
		fprintf(hf,"\tGO_%s,\n",opt_buf[i]);
	}

    fprintf(hf,"\n} enumGetOpt;\n");
    opt_buf['?'] = 0;


    //----- print option index

    print_section(cf,sep1,"OptionUsed & OptionIndex");

    fprintf(cf,"u8 OptionUsed[OPT__N_TOTAL+1] = {0};\n\n");
    var_ptr += snprintf(var_ptr,var_end-var_ptr,
		"extern u8 OptionUsed[OPT__N_TOTAL+1];\n");

    fprintf(cf,"const u8 OptionIndex[OPT_INDEX_SIZE] = \n{\n");
    var_ptr += snprintf(var_ptr,var_end-var_ptr,
		"extern const u8 OptionIndex[OPT_INDEX_SIZE];\n");

    for ( i = 0; i < OPT_INDEX_SIZE; )
    {
	int start = i;
	while ( i < OPT_INDEX_SIZE && !opt_buf[i] )
	    i++;
	int len = i - start;
	while ( len > 0 )
	{
	    const int now_len = len < 16 ? len : 16 - start % 16;
	    fprintf(cf,"\t/* 0x%02x   */\t %.*s\n",
		    start,
		    2*now_len + now_len/4,
		    "0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0," );
	    start += now_len;
	    len -= now_len;
	}
	    
	while ( i < OPT_INDEX_SIZE && opt_buf[i] )
	{
	    fprintf(cf,"\t/* 0x%02x %c */\tOPT_%s,\n",
		i, i > ' ' && i < 0x7f ? i : ' ', opt_buf[i]);
	    i++;
	}
    }
    fprintf(cf,"};\n");


    //----- option allowed

    if (ctrl->opt_allow_cmd)
    {
	print_section(cf,sep1,"opt_allowed_cmd_*");
	for ( info = ctrl->info; info < ctrl->end; info++ )
	{
	    if ( !( info->type & T_DEF_CMD ) )
		continue;

	    fprintf(cf,"static u8 option_allowed_cmd_%s[%u] = // cmd #%u\n{",
		info->c_name, ctrl->n_opt_specific, info->index );

	    int i;
	    u8 * ptr = ctrl->opt_allow_cmd + info->index * ctrl->n_opt_specific;
	    for ( i = 0; i < ctrl->n_opt_specific; i++ )
		fprintf(cf, "%s%u%s",
			    !(i%30) ? "\n    " : !(i%10) ? "  " : !(i%5) ? " " : "",
			    ptr[i],
			    i < ctrl->n_opt_specific-1 ? "," : "" );

	    fprintf(cf,"\n};\n\n");
	}
    }

    //----- InfoCommand

    print_links(ctrl);
    var_ptr += snprintf(var_ptr,var_end-var_ptr,
		"extern const InfoCommand_t CommandInfo[CMD__N+1];\n");

    //----- InfoUI

    print_section(cf,sep1,"InfoUI");

    var_ptr += snprintf(var_ptr,var_end-var_ptr,
		"extern const InfoUI_t InfoUI;\n");

    fprintf(cf,
	    "const InfoUI_t InfoUI =\n"
	    "{\n"
	    "\t\"%s\",\n"	// tool_name
	    "\t%s\n"		// n_cmd
	    "\t%s\n"		// cmd_tab
	    "\tCommandInfo,\n"	// cmd_info
	    "\t%s\n"		// n_opt_specific
	    "\tOPT__N_TOTAL,\n"	// n_opt_total
	    "\tOptionInfo,\n"	// opt_info
	    "\tOptionUsed,\n"	// opt_used
	    "\tOptionIndex,\n"	// opt_index
	    "\tOptionShort,\n"	// opt_short
	    "\tOptionLong\n"	// opt_long
	    "};\n",
	    ctrl->info->c_name,
	    ctrl->n_cmd ? "CMD__N," : "0, // n_cmd",
	    ctrl->n_cmd ? "CommandTab," : "0, // cmd_tab",
	    ctrl->n_cmd ? "OPT__N_SPECIFIC," : "0, // n_opt_specific" );


    //----- external vars

    print_section(hf,sep1,"external vars");
    fputs(var_buf,hf);


    //----- terminate

    print_section(cf,sep1,"END");
    print_section(hf,sep1,"END");
    fprintf(hf,"#endif // %s\n\n",guard);

    return ERR_OK;
};
static void format_thread_info(FILE *fp, struct emailinfo *email,
			       int level, int *num_replies,
			       struct emailinfo* subdir_email, FILE *fp_body,
			       int threadnum, bool is_first)
{
    char *subj, *tmpname;
    char *href = NULL;
    char buffer[256];
    char *first_attributes = (is_first) ? " accesskey=\"j\" name=\"first\" id=\"first\"" : "";

#ifdef HAVE_ICONV
    subj = convchars(email->subject, "utf-8");
    tmpname = convchars(email->name, "utf-8");
#else
    subj = convchars(email->subject, email->charset);
    tmpname = convchars(email->name, email->charset);
#endif

    if (set_files_by_thread) {
	int maybe_reply = 0;
	int is_reply = 1;
	fprintf(fp_body, "<a name =\"%.4d\" id=\"%.4d\"></a>", email->msgnum, email->msgnum);
	print_headers(fp_body, email, TRUE);
	if ((set_show_msg_links && set_show_msg_links != 4) || !set_usetable) {
	    fprintf(fp_body, "</ul>\n");
	}
	/* maybe_reply only affects code in finelink.c which we don't want to run twice? */
	printbody(fp_body, email, maybe_reply, is_reply);
	if (level == 0) {
	    sprintf(buffer, "thread_body%d.%s",
		    threadnum, set_htmlsuffix);
	    href = buffer;
	}
	is_reply = print_links(fp_body, email, PAGE_TOP, TRUE);
    }
    if (!href)
	href = msg_href(email, subdir_email, FALSE);

    /* Print the thread info */
    if (set_indextable) {
	fprintf(fp,
		"<tr><td>%s<a href=\"%s\"%s><strong>%s</strong></a></td>"
		"<td nowrap><a name=\"%d\" id=\"%d\">%s</a></td>" "<td nowrap>%s</td></tr>\n",
		level > 1 ? "--&gt; " : "", 
		href, first_attributes,
		subj, email->msgnum, email->msgnum, tmpname, getindexdatestr(email->date));
    }
    else {
        if (num_open_li[level] != 0) {
	  fprintf (fp, "</li>\n");
	  num_open_li[level]--;
	}
	fprintf(fp, "<li><a href=\"%s\"%s>%s</a>&nbsp;"
		"<a name=\"%d\" id=\"%d\"><em>%s</em></a>&nbsp;<em>(%s)</em>\n", 
		href, first_attributes, 
		subj, email->msgnum, email->msgnum, tmpname, getindexdatestr(email->date));
    }
    if (subj)
      free(subj);
    if (tmpname)
      free(tmpname);
    ++num_replies[level];
    if (!set_indextable)
      ++num_open_li[level];
    email->flags |= PRINT_THREAD;	/* its written now */
}