Ignore:
Timestamp:
Apr 19, 2000, 4:46:07 PM (25 years ago)
Author:
sandervl
Message:

update with latest wine code

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/wrc/writeres.c

    r979 r3426  
    66 */
    77
    8 /*******************************************************************************
    9 *   Defined Constants And Macros                                               *
    10 *******************************************************************************/
     8#include "config.h"
     9
     10#include <stdio.h>
     11#include <stdlib.h>
     12#include <string.h>
     13#include <assert.h>
     14#include <time.h>
     15
     16#include "wrc.h"
     17#include "writeres.h"
     18#include "genres.h"
     19#include "newstruc.h"
     20#include "utils.h"
     21
     22#ifdef NEED_UNDERSCORE_PREFIX
     23char Underscore[] = "_";
     24#else
     25char Underscore[] = "";
     26#endif
     27
    1128#define MASM 1
    1229#ifdef MASM
     
    2340    #define COMMENT_LINE    ";"
    2441    #define OR              "or"
     42char s_file_head_str[] =
     43        ";/* This file is generated with wrc version " WRC_FULLVERSION ". Do not edit! */\n"
     44        ";/* Source : %s */\n"
     45        ";/* Cmdline: %s */\n"
     46        ";/* Date   : %s */\n"
     47        "\n"
     48        "\t.386p\n"
     49        "\t.model flat\n"
     50        "\t.data\n"
     51        "\n"
     52        ;
     53
     54char s_file_tail_str[] =
     55        "\tend\n"
     56        ";/* <eof> */\n"
     57        "\n"
     58        ;
     59
    2560#else
    2661    #define DIRECTIVE_BYTE  ".byte"
     
    3671    #define COMMENT_LINE
    3772    #define OR              "|"
     73
     74char s_file_head_str[] =
     75        "/* This file is generated with wrc version " WRC_FULLVERSION ". Do not edit! */\n"
     76        "/* Source : %s */\n"
     77        "/* Cmdline: %s */\n"
     78        "/* Date   : %s */\n"
     79        "\n"
     80        "\t.data\n"
     81        "\n"
     82        ;
     83
     84char s_file_tail_str[] =
     85        "/* <eof> */\n"
     86        "\n"
     87        ;
     88
    3889#endif
    3990
    40 /*******************************************************************************
    41 *   Header Files                                                               *
    42 *******************************************************************************/
    43 #include "config.h"
    44 
    45 #include <stdio.h>
    46 #include <stdlib.h>
    47 #include <string.h>
    48 #include <assert.h>
    49 #include <time.h>
    50 
    51 #include "wrc.h"
    52 #include "writeres.h"
    53 #include "genres.h"
    54 #include "newstruc.h"
    55 #include "utils.h"
    56 
     91char s_file_autoreg_str[] =
     92        "\t.text\n"
     93        ".LAuto_Register:\n"
     94        "\tpushl\t$%s%s\n"
    5795#ifdef NEED_UNDERSCORE_PREFIX
    58 char Underscore[] = "_";
     96        "\tcall\t_LIBRES_RegisterResources\n"
    5997#else
    60 char Underscore[] = "";
     98        "\tcall\tLIBRES_RegisterResources\n"
    6199#endif
    62 
    63 char s_file_head_str[] =
    64     COMMENT_LINE"/* This file is generated with wrc version " WRC_FULLVERSION ". Do not edit! */\n"
    65     COMMENT_LINE"/* Source : %s */\n"
    66     COMMENT_LINE"/* Cmdline: %s */\n"
    67     COMMENT_LINE"/* Date   : %s */\n"
    68                 "\n"
    69     #ifdef MASM
    70                 "\t.386p\n"
    71                 "\t.model flat\n"
    72     #endif
    73                 "\t.data\n"
    74                 "\n"
    75     ;
    76 
    77 char s_file_tail_str[] =
    78 #ifdef MASM
    79     "\tend\n"
     100        "\taddl\t$4,%%esp\n"
     101        "\tret\n\n"
     102#ifdef __NetBSD__
     103        ".stabs \"___CTOR_LIST__\",22,0,0,.LAuto_Register\n\n"
    80104#else
    81     "/* <eof> */\n"
    82     "\n"
     105        "\t.section .ctors,\"aw\"\n"
     106        "\t.long\t.LAuto_Register\n\n"
    83107#endif
    84     ;
    85 
    86 char s_file_autoreg_str[] =
    87 #ifdef MASM
    88     ""
    89 #else
    90     "\t.text\n"
    91     LOCAL_PREFIX"LAuto_Register:\n"
    92     "\tpushl\t$%s%s\n"
    93 #ifdef NEED_UNDERSCORE_PREFIX
    94     "\tcall\t_LIBRES_RegisterResources\n"
    95 #else
    96     "\tcall\tLIBRES_RegisterResources\n"
    97 #endif
    98     "\taddl\t$4,%%esp\n"
    99     "\tret\n\n"
    100 #ifdef __NetBSD__
    101     ".stabs \"___CTOR_LIST__\",22,0,0,.LAuto_Register\n\n"
    102 #else
    103     "\t.section .ctors,\"aw\"\n"
    104     "\t"DIRECTIVE_LONG"\t.LAuto_Register\n\n"
    105 #endif
    106 #endif
    107     ;
     108        ;
    108109
    109110char h_file_head_str[] =
    110     "/*\n"
    111     " * This file is generated with wrc version " WRC_FULLVERSION ". Do not edit!\n"
    112     " * Source : %s\n"
    113     " * Cmdline: %s\n"
    114     " * Date   : %s"
    115     " */\n"
     111        "/*\n"
     112        " * This file is generated with wrc version " WRC_FULLVERSION ". Do not edit!\n"
     113        " * Source : %s\n"
     114        " * Cmdline: %s\n"
     115        " * Date   : %s"
     116        " */\n"
    116117        "\n"
    117     "#ifndef __%08lx_H\n"   /* This becomes the date of compile */
    118     "#define __%08lx_H\n"
    119     "\n"
    120     "#include <wrc_rsc.h>\n"
    121     "\n"
    122     ;
     118        "#ifndef __%08lx_H\n"   /* This becomes the date of compile */
     119        "#define __%08lx_H\n"
     120        "\n"
     121        "#include <wrc_rsc.h>\n"
     122        "\n"
     123        ;
    123124
    124125char h_file_tail_str[] =
    125     "#endif\n"
    126     "/* <eof> */\n\n"
    127     ;
     126        "#endif\n"
     127        "/* <eof> */\n\n"
     128        ;
    128129
    129130char _NEResTab[] = "_NEResTab";
     
    132133
    133134/* Variables used for resource sorting */
    134 res_count_t *rcarray = NULL;    /* Type-level count array */
    135 int rccount = 0;        /* Nr of entries in the type-level array */
    136 int n_id_entries = 0;       /* win32 only: Nr of unique ids in the type-level array */
    137 int n_name_entries = 0;     /* win32 only: Nr of unique namess in the type-level array */
    138 
    139 static int direntries;      /* win32 only: Total number of unique resources */
     135res_count_t *rcarray = NULL;    /* Type-level count array */
     136int rccount = 0;                /* Nr of entries in the type-level array */
     137int n_id_entries = 0;           /* win32 only: Nr of unique ids in the type-level array */
     138int n_name_entries = 0;         /* win32 only: Nr of unique namess in the type-level array */
     139
     140static int direntries;          /* win32 only: Total number of unique resources */
    140141
    141142time_t now;
     
    143144/*
    144145 *****************************************************************************
    145  * Function : write_resfile
    146  * Syntax   : void write_resfile(char *outname, resource_t *top)
    147  * Input    :
    148  *  outname - Filename to write to
    149  *  top - The resource-tree to convert
    150  * Output   :
    151  * Description  :
    152  * Remarks  :
     146 * Function     : write_resfile
     147 * Syntax       : void write_resfile(char *outname, resource_t *top)
     148 * Input        :
     149 *      outname - Filename to write to
     150 *      top     - The resource-tree to convert
     151 * Output       :
     152 * Description  :
     153 * Remarks      :
    153154 *****************************************************************************
    154155*/
    155156void write_resfile(char *outname, resource_t *top)
    156157{
    157     FILE *fo;
    158     int ret;
    159     char zeros[3] = {0, 0, 0};
    160 
    161     fo = fopen(outname, "wb");
    162     if(!fo)
    163     {
    164         error("Could not open %s\n", outname);
    165     }
    166 
    167     if(win32)
    168     {
    169         /* Put an empty resource first to signal win32 format */
    170         res_t *res = new_res();
    171         put_dword(res, 0);      /* ResSize */
    172         put_dword(res, 0x00000020); /* HeaderSize */
    173         put_word(res, 0xffff);      /* ResType */
    174         put_word(res, 0);
    175         put_word(res, 0xffff);      /* ResName */
    176         put_word(res, 0);
    177         put_dword(res, 0);      /* DataVersion */
    178         put_word(res, 0);       /* Memory options */
    179         put_word(res, 0);       /* Language */
    180         put_dword(res, 0);      /* Version */
    181         put_dword(res, 0);      /* Charateristics */
    182         ret = fwrite(res->data, 1, res->size, fo);
    183         if(ret != res->size)
    184         {
    185             fclose(fo);
    186             error("Error writing %s", outname);
    187         }
    188         free(res);
    189     }
    190 
    191     for(; top; top = top->next)
    192     {
    193         if(!top->binres)
    194             continue;
    195 
    196         ret = fwrite(top->binres->data, 1, top->binres->size, fo);
    197         if(ret != top->binres->size)
    198         {
    199             fclose(fo);
    200             error("Error writing %s", outname);
    201         }
    202         if(win32 && (top->binres->size & 0x03))
    203         {
    204             /* Write padding */
    205             ret = fwrite(zeros, 1, 4 - (top->binres->size & 0x03), fo);
    206             if(ret != 4 - (top->binres->size & 0x03))
    207             {
    208                 fclose(fo);
    209                 error("Error writing %s", outname);
    210             }
    211         }
    212     }
    213     fclose(fo);
     158        FILE *fo;
     159        int ret;
     160        char zeros[3] = {0, 0, 0};
     161
     162        fo = fopen(outname, "wb");
     163        if(!fo)
     164        {
     165                error("Could not open %s\n", outname);
     166        }
     167
     168        if(win32)
     169        {
     170                /* Put an empty resource first to signal win32 format */
     171                res_t *res = new_res();
     172                put_dword(res, 0);              /* ResSize */
     173                put_dword(res, 0x00000020);     /* HeaderSize */
     174                put_word(res, 0xffff);          /* ResType */
     175                put_word(res, 0);
     176                put_word(res, 0xffff);          /* ResName */
     177                put_word(res, 0);
     178                put_dword(res, 0);              /* DataVersion */
     179                put_word(res, 0);               /* Memory options */
     180                put_word(res, 0);               /* Language */
     181                put_dword(res, 0);              /* Version */
     182                put_dword(res, 0);              /* Charateristics */
     183                ret = fwrite(res->data, 1, res->size, fo);
     184                if(ret != res->size)
     185                {
     186                        fclose(fo);
     187                        error("Error writing %s", outname);
     188                }
     189                free(res);
     190        }
     191
     192        for(; top; top = top->next)
     193        {
     194                if(!top->binres)
     195                        continue;
     196
     197                ret = fwrite(top->binres->data, 1, top->binres->size, fo);
     198                if(ret != top->binres->size)
     199                {
     200                        fclose(fo);
     201                        error("Error writing %s", outname);
     202                }
     203                if(win32 && (top->binres->size & 0x03))
     204                {
     205                        /* Write padding */
     206                        ret = fwrite(zeros, 1, 4 - (top->binres->size & 0x03), fo);
     207                        if(ret != 4 - (top->binres->size & 0x03))
     208                        {
     209                                fclose(fo);
     210                                error("Error writing %s", outname);
     211                        }
     212                }
     213        }
     214        fclose(fo);
    214215}
    215216
    216217/*
    217218 *****************************************************************************
    218  * Function : write_s_res
    219  * Syntax   : void write_s_res(FILE *fp, res_t *res)
    220  * Input    :
    221  * Output   :
    222  * Description  :
    223  * Remarks  :
     219 * Function     : write_s_res
     220 * Syntax       : void write_s_res(FILE *fp, res_t *res)
     221 * Input        :
     222 * Output       :
     223 * Description  :
     224 * Remarks      :
    224225 *****************************************************************************
    225226*/
    226 #define BYTESPERLINE    8
     227#define BYTESPERLINE    8
    227228void write_s_res(FILE *fp, res_t *res)
    228229{
    229     int idx = res->dataidx;
    230     int end = res->size;
    231     int rest = (end - idx) % BYTESPERLINE;
    232     int lines = (end - idx) / BYTESPERLINE;
    233     int i, j;
    234 
    235     for(i = 0 ; i < lines; i++)
    236     {
    237         fprintf(fp, "\t"DIRECTIVE_BYTE"\t");
    238         for(j = 0; j < BYTESPERLINE; j++, idx++)
    239         {
    240             fprintf(fp, BYTEFRMT"%s", res->data[idx] & 0xff,
    241                     j == BYTESPERLINE-1 ? "" : ", ");
    242         }
    243         fprintf(fp, "\n");
    244     }
    245     if(rest)
    246     {
    247         fprintf(fp, "\t"DIRECTIVE_BYTE"\t");
    248         for(j = 0; j < rest; j++, idx++)
    249         {
    250             fprintf(fp, BYTEFRMT"%s", res->data[idx] & 0xff,
    251                     j == rest-1 ? "" : ", ");
    252         }
    253         fprintf(fp, "\n");
    254     }
     230        int idx = res->dataidx;
     231        int end = res->size;
     232        int rest = (end - idx) % BYTESPERLINE;
     233        int lines = (end - idx) / BYTESPERLINE;
     234        int i, j;
     235
     236        for(i = 0 ; i < lines; i++)
     237        {
     238                fprintf(fp, "\t%s\t", DIRECTIVE_BYTE);
     239                for(j = 0; j < BYTESPERLINE; j++, idx++)
     240                {
     241                        fprintf(fp, BYTEFRMT"%s", res->data[idx] & 0xff,
     242                                        j == BYTESPERLINE-1 ? "" : ", ");
     243                }
     244                fprintf(fp, "\n");
     245        }
     246        if(rest)
     247        {
     248                fprintf(fp, "\t%s\t", DIRECTIVE_BYTE);
     249                for(j = 0; j < rest; j++, idx++)
     250                {
     251                        fprintf(fp, BYTEFRMT"%s", res->data[idx] & 0xff,
     252                                        j == rest-1 ? "" : ", ");
     253                }
     254                fprintf(fp, "\n");
     255        }
    255256}
    256257
    257258/*
    258259 *****************************************************************************
    259  * Function : write_name_str
    260  * Syntax   : void write_name_str(FILE *fp, name_id_t *nid)
    261  * Input    :
    262  * Output   :
    263  * Description  :
    264  * Remarks  : One level self recursive for string type conversion
     260 * Function     : write_name_str
     261 * Syntax       : void write_name_str(FILE *fp, name_id_t *nid)
     262 * Input        :
     263 * Output       :
     264 * Description  :
     265 * Remarks      : One level self recursive for string type conversion
    265266 *****************************************************************************
    266267*/
    267268void write_name_str(FILE *fp, name_id_t *nid)
    268269{
    269     res_t res;
    270     assert(nid->type == name_str);
    271 
    272     if(!win32 && nid->name.s_name->type == str_char)
    273     {
    274         res.size = strlen(nid->name.s_name->str.cstr);
    275         if(res.size > 254)
    276             error("Can't write strings larger than 254 bytes");
    277         if(res.size == 0)
    278             internal_error(__FILE__, __LINE__, "Attempt to write empty string");
    279         res.dataidx = 0;
    280         res.data = (char *)xmalloc(res.size + 1);
    281         res.data[0] = (char)res.size;
    282         res.size++; /* We need to write the lenth byte as well */
    283         strcpy(res.data+1, nid->name.s_name->str.cstr);
    284         write_s_res(fp, &res);
    285         free(res.data);
    286     }
    287     else if(!win32 && nid->name.s_name->type == str_unicode)
    288     {
    289         name_id_t lnid;
    290         string_t str;
    291 
    292         lnid.type = name_str;
    293         lnid.name.s_name = &str;
    294         str.type = str_char;
    295         str.str.cstr = dupwstr2cstr(nid->name.s_name->str.wstr);
    296         write_name_str(fp, &lnid);
    297         free(str.str.cstr);
    298     }
    299     else if(win32 && nid->name.s_name->type == str_char)
    300     {
    301         name_id_t lnid;
    302         string_t str;
    303 
    304         lnid.type = name_str;
    305         lnid.name.s_name = &str;
    306         str.type = str_unicode;
    307         str.str.wstr = dupcstr2wstr(nid->name.s_name->str.cstr);
    308         write_name_str(fp, &lnid);
    309         free(str.str.wstr);
    310     }
    311     else  if(win32 && nid->name.s_name->type == str_unicode)
    312     {
    313         res.size = wstrlen(nid->name.s_name->str.wstr);
    314         if(res.size > 65534)
    315             error("Can't write strings larger than 65534 bytes");
    316         if(res.size == 0)
    317             internal_error(__FILE__, __LINE__, "Attempt to write empty string");
    318         res.dataidx = 0;
    319         res.data = (char *)xmalloc((res.size + 1) * 2);
    320         ((short *)res.data)[0] = (short)res.size;
    321         wstrcpy((short *)(res.data+2), nid->name.s_name->str.wstr);
    322         res.size *= 2; /* Function writes bytes, not shorts... */
    323         res.size += 2; /* We need to write the length word as well */
    324         write_s_res(fp, &res);
    325         free(res.data);
    326     }
    327     else
    328     {
    329         internal_error(__FILE__, __LINE__, "Hmm, requested to write a string of unknown type %d",
    330                 nid->name.s_name->type);
    331     }
     270        res_t res;
     271        assert(nid->type == name_str);
     272
     273        if(!win32 && nid->name.s_name->type == str_char)
     274        {
     275                res.size = strlen(nid->name.s_name->str.cstr);
     276                if(res.size > 254)
     277                        error("Can't write strings larger than 254 bytes");
     278                if(res.size == 0)
     279                        internal_error(__FILE__, __LINE__, "Attempt to write empty string");
     280                res.dataidx = 0;
     281                res.data = (char *)xmalloc(res.size + 1);
     282                res.data[0] = (char)res.size;
     283                res.size++;     /* We need to write the lenth byte as well */
     284                strcpy(res.data+1, nid->name.s_name->str.cstr);
     285                write_s_res(fp, &res);
     286                free(res.data);
     287        }
     288        else if(!win32 && nid->name.s_name->type == str_unicode)
     289        {
     290                name_id_t lnid;
     291                string_t str;
     292
     293                lnid.type = name_str;
     294                lnid.name.s_name = &str;
     295                str.type = str_char;
     296                str.str.cstr = dupwstr2cstr(nid->name.s_name->str.wstr);
     297                write_name_str(fp, &lnid);
     298                free(str.str.cstr);
     299        }
     300        else if(win32 && nid->name.s_name->type == str_char)
     301        {
     302                name_id_t lnid;
     303                string_t str;
     304
     305                lnid.type = name_str;
     306                lnid.name.s_name = &str;
     307                str.type = str_unicode;
     308                str.str.wstr = dupcstr2wstr(nid->name.s_name->str.cstr);
     309                write_name_str(fp, &lnid);
     310                free(str.str.wstr);
     311        }
     312        else  if(win32 && nid->name.s_name->type == str_unicode)
     313        {
     314                res.size = wstrlen(nid->name.s_name->str.wstr);
     315                if(res.size > 65534)
     316                        error("Can't write strings larger than 65534 bytes");
     317                if(res.size == 0)
     318                        internal_error(__FILE__, __LINE__, "Attempt to write empty string");
     319                res.dataidx = 0;
     320                res.data = (char *)xmalloc((res.size + 1) * 2);
     321                ((short *)res.data)[0] = (short)res.size;
     322                wstrcpy((short *)(res.data+2), nid->name.s_name->str.wstr);
     323                res.size *= 2; /* Function writes bytes, not shorts... */
     324                res.size += 2; /* We need to write the length word as well */
     325                write_s_res(fp, &res);
     326                free(res.data);
     327        }
     328        else
     329        {
     330                internal_error(__FILE__, __LINE__, "Hmm, requested to write a string of unknown type %d",
     331                                nid->name.s_name->type);
     332        }
    332333}
    333334
    334335/*
    335336 *****************************************************************************
    336  * Function : compare_name_id
    337  * Syntax   : int compare_name_id(name_id_t *n1, name_id_t *n2)
    338  * Input    :
    339  * Output   :
    340  * Description  :
    341  * Remarks  :
     337 * Function     : compare_name_id
     338 * Syntax       : int compare_name_id(name_id_t *n1, name_id_t *n2)
     339 * Input        :
     340 * Output       :
     341 * Description  :
     342 * Remarks      :
    342343 *****************************************************************************
    343344*/
    344345int compare_name_id(name_id_t *n1, name_id_t *n2)
    345346{
    346     if(n1->type == name_ord && n2->type == name_ord)
    347     {
    348         return n1->name.i_name - n2->name.i_name;
    349     }
    350     else if(n1->type == name_str && n2->type == name_str)
    351     {
    352         if(n1->name.s_name->type == str_char
    353         && n2->name.s_name->type == str_char)
    354         {
    355             return strcasecmp(n1->name.s_name->str.cstr, n2->name.s_name->str.cstr);
    356         }
    357         else if(n1->name.s_name->type == str_unicode
    358         && n2->name.s_name->type == str_unicode)
    359         {
    360             return wstricmp(n1->name.s_name->str.wstr, n2->name.s_name->str.wstr);
    361         }
    362         else
    363         {
    364             internal_error(__FILE__, __LINE__, "Can't yet compare strings of mixed type");
    365         }
    366     }
    367     else if(n1->type == name_ord && n2->type == name_str)
    368         return 1;
    369     else if(n1->type == name_str && n2->type == name_ord)
    370         return -1;
    371     else
    372         internal_error(__FILE__, __LINE__, "Comparing name-ids with unknown types (%d, %d)",
    373                 n1->type, n2->type);
    374 
    375     return 0; /* Keep the compiler happy */
     347        if(n1->type == name_ord && n2->type == name_ord)
     348        {
     349                return n1->name.i_name - n2->name.i_name;
     350        }
     351        else if(n1->type == name_str && n2->type == name_str)
     352        {
     353                if(n1->name.s_name->type == str_char
     354                && n2->name.s_name->type == str_char)
     355                {
     356                        return strcasecmp(n1->name.s_name->str.cstr, n2->name.s_name->str.cstr);
     357                }
     358                else if(n1->name.s_name->type == str_unicode
     359                && n2->name.s_name->type == str_unicode)
     360                {
     361                        return wstricmp(n1->name.s_name->str.wstr, n2->name.s_name->str.wstr);
     362                }
     363                else
     364                {
     365                        internal_error(__FILE__, __LINE__, "Can't yet compare strings of mixed type");
     366                }
     367        }
     368        else if(n1->type == name_ord && n2->type == name_str)
     369                return 1;
     370        else if(n1->type == name_str && n2->type == name_ord)
     371                return -1;
     372        else
     373                internal_error(__FILE__, __LINE__, "Comparing name-ids with unknown types (%d, %d)",
     374                                n1->type, n2->type);
     375
     376        return 0; /* Keep the compiler happy */
    376377}
    377378
    378379/*
    379380 *****************************************************************************
    380  * Function : find_counter
    381  * Syntax   : res_count_t *find_counter(name_id_t *type)
    382  * Input    :
    383  * Output   :
    384  * Description  :
    385  * Remarks  :
     381 * Function     : find_counter
     382 * Syntax       : res_count_t *find_counter(name_id_t *type)
     383 * Input        :
     384 * Output       :
     385 * Description  :
     386 * Remarks      :
    386387 *****************************************************************************
    387388*/
    388389res_count_t *find_counter(name_id_t *type)
    389390{
    390     int i;
    391     for(i = 0; i < rccount; i++)
    392     {
    393         if(!compare_name_id(type, &(rcarray[i].type)))
    394             return &rcarray[i];
    395     }
    396     return NULL;
     391        int i;
     392        for(i = 0; i < rccount; i++)
     393        {
     394                if(!compare_name_id(type, &(rcarray[i].type)))
     395                        return &rcarray[i];
     396        }
     397        return NULL;
    397398}
    398399
    399400/*
    400401 *****************************************************************************
    401  * Function : count_resources
    402  * Syntax   : res_count_t *count_resources(resource_t *top)
    403  * Input    :
    404  * Output   :
    405  * Description  :
    406  * Remarks  : The whole lot is converted into arrays because they are
    407  *        easy sortable. Makes the lot almost unreadable, but it
    408  *        works (I hope). Basically you have to keep in mind that
    409  *        the lot is a three-dimensional structure for win32 and a
    410  *        two-dimensional structure for win16.
     402 * Function     : count_resources
     403 * Syntax       : res_count_t *count_resources(resource_t *top)
     404 * Input        :
     405 * Output       :
     406 * Description  :
     407 * Remarks      : The whole lot is converted into arrays because they are
     408 *                easy sortable. Makes the lot almost unreadable, but it
     409 *                works (I hope). Basically you have to keep in mind that
     410 *                the lot is a three-dimensional structure for win32 and a
     411 *                two-dimensional structure for win16.
    411412 *****************************************************************************
    412413*/
    413 #define RCT(v)  (*((resource_t **)(v)))
     414#define RCT(v)  (*((resource_t **)(v)))
    414415/* qsort sorting function */
    415416int sort_name_id(const void *e1, const void *e2)
    416417{
    417     return compare_name_id(RCT(e1)->name, RCT(e2)->name);
     418        return compare_name_id(RCT(e1)->name, RCT(e2)->name);
    418419}
    419420
    420421int sort_language(const void *e1, const void *e2)
    421422{
    422     assert((RCT(e1)->lan) != NULL);
    423     assert((RCT(e2)->lan) != NULL);
    424 
    425     return MAKELANGID(RCT(e1)->lan->id, RCT(e1)->lan->sub)
    426          - MAKELANGID(RCT(e2)->lan->id, RCT(e2)->lan->sub);
     423        assert((RCT(e1)->lan) != NULL);
     424        assert((RCT(e2)->lan) != NULL);
     425
     426        return MAKELANGID(RCT(e1)->lan->id, RCT(e1)->lan->sub)
     427             - MAKELANGID(RCT(e2)->lan->id, RCT(e2)->lan->sub);
    427428}
    428429#undef RCT
    429 #define RCT(v)  ((res_count_t *)(v))
     430#define RCT(v)  ((res_count_t *)(v))
    430431int sort_type(const void *e1, const void *e2)
    431432{
    432     return compare_name_id(&(RCT(e1)->type), &(RCT(e2)->type));
     433        return compare_name_id(&(RCT(e1)->type), &(RCT(e2)->type));
    433434}
    434435#undef RCT
     
    436437void count_resources(resource_t *top)
    437438{
    438     resource_t *rsc;
    439     res_count_t *rcp;
    440     name_id_t nid;
    441     int i, j;
    442 
    443     for(rsc = top; rsc; rsc = rsc->next)
    444     {
    445         if(!rsc->binres)
    446             continue;
    447         switch(rsc->type)
    448         {
    449         case res_dlgex:
    450             nid.name.i_name = WRC_RT_DIALOG;
    451             nid.type = name_ord;
    452             break;
    453         case res_menex:
    454             nid.name.i_name = WRC_RT_MENU;
    455             nid.type = name_ord;
    456             break;
    457         case res_usr:
    458             nid = *(rsc->res.usr->type);
    459             break;
    460         default:
    461             nid.name.i_name = rsc->type;
    462             nid.type = name_ord;
    463         }
    464 
    465         if((rcp = find_counter(&nid)) == NULL)
    466         {
    467             /* Count the number of uniq ids and names */
    468 
    469             if(nid.type == name_ord)
    470                 n_id_entries++;
    471             else
    472                 n_name_entries++;
    473 
    474             if(!rcarray)
    475             {
    476                 rcarray = (res_count_t *)xmalloc(sizeof(res_count_t));
    477                 rccount = 1;
    478                 rcarray[0].count = 1;
    479                 rcarray[0].type = nid;
    480                 rcarray[0].rscarray = (resource_t **)xmalloc(sizeof(resource_t *));
    481                 rcarray[0].rscarray[0] = rsc;
    482             }
    483             else
    484             {
    485                 rccount++;
    486                 rcarray = (res_count_t *)xrealloc(rcarray, rccount * sizeof(res_count_t));
    487                 rcarray[rccount-1].count = 1;
    488                 rcarray[rccount-1].type = nid;
    489                 rcarray[rccount-1].rscarray = (resource_t **)xmalloc(sizeof(resource_t *));
    490                 rcarray[rccount-1].rscarray[0] = rsc;
    491             }
    492         }
    493         else
    494         {
    495             rcp->count++;
    496             rcp->rscarray = (resource_t **)xrealloc(rcp->rscarray, rcp->count * sizeof(resource_t *));
    497             rcp->rscarray[rcp->count-1] = rsc;
    498         }
    499     }
    500 
    501     if(!win32)
    502     {
    503         /* We're done, win16 requires no special sorting */
    504         return;
    505     }
    506 
    507     /* We now have a unsorted list of types with an array of res_count_t
    508     * in rcarray[0..rccount-1]. And we have names of one type in the
    509     * rcarray[x].rsc[0..rcarray[x].count-1] arrays.
    510     * The list needs to be sorted for win32's top level tree structure.
    511     */
    512 
    513     /* Sort the types */
    514     if(rccount > 1)
    515         qsort(rcarray, rccount, sizeof(rcarray[0]), sort_type);
    516 
    517     /* Now sort the name-id arrays */
    518     for(i = 0; i < rccount; i++)
    519     {
    520         if(rcarray[i].count > 1)
    521             qsort(rcarray[i].rscarray, rcarray[i].count, sizeof(rcarray[0].rscarray[0]), sort_name_id);
    522     }
    523 
    524     /* Now split the name-id arrays into name/language
    525     * subs. Don't look at the awfull expressions...
    526     * We do this by taking the array elements out of rscarray and putting
    527     * together a new array in rsc32array.
    528     */
    529     for(i = 0; i < rccount; i++)
    530     {
    531         res_count_t *rcap;
    532 
    533         assert(rcarray[i].count >= 1);
    534 
    535         /* rcap points to the current type we are dealing with */
    536         rcap = &(rcarray[i]);
    537 
    538         /* Insert the first name-id */
    539         rcap->rsc32array = (res32_count_t *)xmalloc(sizeof(res32_count_t));
    540         rcap->count32 = 1;
    541         rcap->rsc32array[0].rsc = (resource_t **)xmalloc(sizeof(resource_t *));
    542         rcap->rsc32array[0].count = 1;
    543         rcap->rsc32array[0].rsc[0] = rcap->rscarray[0];
    544         if(rcap->rscarray[0]->name->type == name_ord)
    545         {
    546             rcap->n_id_entries = 1;
    547             rcap->n_name_entries = 0;
    548         }
    549         else
    550         {
    551             rcap->n_id_entries = 0;
    552             rcap->n_name_entries = 1;
    553         }
    554 
    555         /* Now loop over the resting resources of the current type
    556         * to find duplicate names (which should have different
    557         * languages).
    558         */
    559         for(j = 1; j < rcap->count; j++)
    560         {
    561             res32_count_t *r32cp;
    562 
    563             /* r32cp points to the current res32_count structure
    564             * that holds the resource name we are processing.
    565             */
    566             r32cp = &(rcap->rsc32array[rcap->count32-1]);
    567 
    568             if(!compare_name_id(r32cp->rsc[0]->name, rcarray[i].rscarray[j]->name))
    569             {
    570                 /* Names are the same, add to list */
    571                 r32cp->count++;
    572                 r32cp->rsc = (resource_t **)xrealloc(r32cp->rsc, r32cp->count * sizeof(resource_t *));
    573                 r32cp->rsc[r32cp->count-1] = rcap->rscarray[j];
    574             }
    575             else
    576             {
    577                 /* New name-id, sort the old one by
    578                 * language and create new list
    579                 */
    580                 if(r32cp->count > 1)
    581                     qsort(r32cp->rsc, r32cp->count, sizeof(r32cp->rsc[0]), sort_language);
    582                 rcap->count32++;
    583                 rcap->rsc32array = (res32_count_t*)xrealloc(rcap->rsc32array, rcap->count32 * sizeof(res32_count_t));
    584                 rcap->rsc32array[rcap->count32-1].rsc = (resource_t **)xmalloc(sizeof(resource_t *));
    585                 rcap->rsc32array[rcap->count32-1].count = 1;
    586                 rcap->rsc32array[rcap->count32-1].rsc[0] = rcap->rscarray[j];
    587 
    588                 if(rcap->rscarray[j]->name->type == name_ord)
    589                     rcap->n_id_entries++;
    590                 else
    591                     rcap->n_name_entries++;
    592             }
    593         }
    594         /* Also sort the languages of the last name group */
    595         if(rcap->rsc32array[rcap->count32-1].count > 1)
    596             qsort(rcap->rsc32array[rcap->count32-1].rsc,
    597                   rcap->rsc32array[rcap->count32-1].count,
    598                   sizeof(rcap->rsc32array[rcap->count32-1].rsc[0]),
    599                   sort_language);
    600     }
     439        resource_t *rsc;
     440        res_count_t *rcp;
     441        name_id_t nid;
     442        int i, j;
     443
     444        for(rsc = top; rsc; rsc = rsc->next)
     445        {
     446                if(!rsc->binres)
     447                        continue;
     448                switch(rsc->type)
     449                {
     450                case res_dlgex:
     451                        nid.name.i_name = WRC_RT_DIALOG;
     452                        nid.type = name_ord;
     453                        break;
     454                case res_menex:
     455                        nid.name.i_name = WRC_RT_MENU;
     456                        nid.type = name_ord;
     457                        break;
     458                case res_usr:
     459                        nid = *(rsc->res.usr->type);
     460                        break;
     461                default:
     462                        nid.name.i_name = rsc->type;
     463                        nid.type = name_ord;
     464                }
     465
     466                if((rcp = find_counter(&nid)) == NULL)
     467                {
     468                        /* Count the number of uniq ids and names */
     469
     470                        if(nid.type == name_ord)
     471                                n_id_entries++;
     472                        else
     473                                n_name_entries++;
     474
     475                        if(!rcarray)
     476                        {
     477                                rcarray = (res_count_t *)xmalloc(sizeof(res_count_t));
     478                                rccount = 1;
     479                                rcarray[0].count = 1;
     480                                rcarray[0].type = nid;
     481                                rcarray[0].rscarray = (resource_t **)xmalloc(sizeof(resource_t *));
     482                                rcarray[0].rscarray[0] = rsc;
     483                        }
     484                        else
     485                        {
     486                                rccount++;
     487                                rcarray = (res_count_t *)xrealloc(rcarray, rccount * sizeof(res_count_t));
     488                                rcarray[rccount-1].count = 1;
     489                                rcarray[rccount-1].type = nid;
     490                                rcarray[rccount-1].rscarray = (resource_t **)xmalloc(sizeof(resource_t *));
     491                                rcarray[rccount-1].rscarray[0] = rsc;
     492                        }
     493                }
     494                else
     495                {
     496                        rcp->count++;
     497                        rcp->rscarray = (resource_t **)xrealloc(rcp->rscarray, rcp->count * sizeof(resource_t *));
     498                        rcp->rscarray[rcp->count-1] = rsc;
     499                }
     500        }
     501
     502        if(!win32)
     503        {
     504                /* We're done, win16 requires no special sorting */
     505                return;
     506        }
     507
     508        /* We now have a unsorted list of types with an array of res_count_t
     509        * in rcarray[0..rccount-1]. And we have names of one type in the
     510        * rcarray[x].rsc[0..rcarray[x].count-1] arrays.
     511        * The list needs to be sorted for win32's top level tree structure.
     512        */
     513
     514        /* Sort the types */
     515        if(rccount > 1)
     516                qsort(rcarray, rccount, sizeof(rcarray[0]), sort_type);
     517
     518        /* Now sort the name-id arrays */
     519        for(i = 0; i < rccount; i++)
     520        {
     521                if(rcarray[i].count > 1)
     522                        qsort(rcarray[i].rscarray, rcarray[i].count, sizeof(rcarray[0].rscarray[0]), sort_name_id);
     523        }
     524
     525        /* Now split the name-id arrays into name/language
     526        * subs. Don't look at the awfull expressions...
     527        * We do this by taking the array elements out of rscarray and putting
     528        * together a new array in rsc32array.
     529        */
     530        for(i = 0; i < rccount; i++)
     531        {
     532                res_count_t *rcap;
     533
     534                assert(rcarray[i].count >= 1);
     535
     536                /* rcap points to the current type we are dealing with */
     537                rcap = &(rcarray[i]);
     538
     539                /* Insert the first name-id */
     540                rcap->rsc32array = (res32_count_t *)xmalloc(sizeof(res32_count_t));
     541                rcap->count32 = 1;
     542                rcap->rsc32array[0].rsc = (resource_t **)xmalloc(sizeof(resource_t *));
     543                rcap->rsc32array[0].count = 1;
     544                rcap->rsc32array[0].rsc[0] = rcap->rscarray[0];
     545                if(rcap->rscarray[0]->name->type == name_ord)
     546                {
     547                        rcap->n_id_entries = 1;
     548                        rcap->n_name_entries = 0;
     549                }
     550                else
     551                {
     552                        rcap->n_id_entries = 0;
     553                        rcap->n_name_entries = 1;
     554                }
     555
     556                /* Now loop over the resting resources of the current type
     557                * to find duplicate names (which should have different
     558                * languages).
     559                */
     560                for(j = 1; j < rcap->count; j++)
     561                {
     562                        res32_count_t *r32cp;
     563
     564                        /* r32cp points to the current res32_count structure
     565                        * that holds the resource name we are processing.
     566                        */
     567                        r32cp = &(rcap->rsc32array[rcap->count32-1]);
     568
     569                        if(!compare_name_id(r32cp->rsc[0]->name, rcarray[i].rscarray[j]->name))
     570                        {
     571                                /* Names are the same, add to list */
     572                                r32cp->count++;
     573                                r32cp->rsc = (resource_t **)xrealloc(r32cp->rsc, r32cp->count * sizeof(resource_t *));
     574                                r32cp->rsc[r32cp->count-1] = rcap->rscarray[j];
     575                        }
     576                        else
     577                        {
     578                                /* New name-id, sort the old one by
     579                                * language and create new list
     580                                */
     581                                if(r32cp->count > 1)
     582                                        qsort(r32cp->rsc, r32cp->count, sizeof(r32cp->rsc[0]), sort_language);
     583                                rcap->count32++;
     584                                rcap->rsc32array = (res32_count_t*)xrealloc(rcap->rsc32array, rcap->count32 * sizeof(res32_count_t));
     585                                rcap->rsc32array[rcap->count32-1].rsc = (resource_t **)xmalloc(sizeof(resource_t *));
     586                                rcap->rsc32array[rcap->count32-1].count = 1;
     587                                rcap->rsc32array[rcap->count32-1].rsc[0] = rcap->rscarray[j];
     588
     589                                if(rcap->rscarray[j]->name->type == name_ord)
     590                                        rcap->n_id_entries++;
     591                                else
     592                                        rcap->n_name_entries++;
     593                        }
     594                }
     595                /* Also sort the languages of the last name group */
     596                if(rcap->rsc32array[rcap->count32-1].count > 1)
     597                        qsort(rcap->rsc32array[rcap->count32-1].rsc,
     598                              rcap->rsc32array[rcap->count32-1].count,
     599                              sizeof(rcap->rsc32array[rcap->count32-1].rsc[0]),
     600                              sort_language);
     601        }
    601602}
    602603
    603604/*
    604605 *****************************************************************************
    605  * Function : write_pe_segment
    606  * Syntax   : void write_pe_segment(FILE *fp, resource_t *top)
    607  * Input    :
    608  * Output   :
    609  * Description  :
    610  * Remarks  :
     606 * Function     : write_pe_segment
     607 * Syntax       : void write_pe_segment(FILE *fp, resource_t *top)
     608 * Input        :
     609 * Output       :
     610 * Description  :
     611 * Remarks      :
    611612 *****************************************************************************
    612613*/
    613614void write_pe_segment(FILE *fp, resource_t *top)
    614615{
    615     int i;
    616 
    617     fprintf(fp, "\t"DIRECTIVE_ALIGN"\t4\n");
    618     fprintf(fp, "%s%s:\n", prefix, _PEResTab);
    619     fprintf(fp, "\t"DIRECTIVE_GLOBAL"\t%s%s\n", prefix, _PEResTab);
    620     /* Flags */
    621     fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n");
    622     /* Time/Date stamp */
    623     fprintf(fp, "\t"DIRECTIVE_LONG"\t"LONGFRMT"\n", (long)now);
    624     /* Version */
    625     fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n");    /* FIXME: must version be filled out? */
    626     /* # of id entries, # of name entries */
    627     fprintf(fp, "\t"DIRECTIVE_WORD"\t%d, %d\n", n_name_entries, n_id_entries);
    628 
    629     /* Write the type level of the tree */
    630     for(i = 0; i < rccount; i++)
    631     {
    632         res_count_t *rcp;
    633         char *label;
    634 
    635         rcp = &rcarray[i];
    636 
    637         /* TypeId */
    638         if(rcp->type.type == name_ord)
    639             fprintf(fp, "\t"DIRECTIVE_LONG"\t%d\n", rcp->type.name.i_name);
    640         else
    641         {
    642             char *name = prep_nid_for_label(&(rcp->type));
    643             fprintf(fp, "\t"DIRECTIVE_LONG"\t(%s_%s_typename - %s%s) "OR" "HEXBIT31"\n",
    644                 prefix,
    645                 name,
    646                 prefix,
    647                 _PEResTab);
    648         }
    649         /* Offset */
    650         label = prep_nid_for_label(&(rcp->type));
    651         fprintf(fp, "\t"DIRECTIVE_LONG"\t("LOCAL_PREFIX"L%s - %s%s) "OR" "HEXBIT31"\n",
    652             label,
    653             prefix,
    654             _PEResTab);
    655     }
    656 
    657     /* Write the name level of the tree */
    658 
    659     for(i = 0; i < rccount; i++)
    660     {
    661         res_count_t *rcp;
    662         char *typelabel;
    663         char *namelabel;
    664         int j;
    665 
    666         rcp = &rcarray[i];
    667 
    668         typelabel = xstrdup(prep_nid_for_label(&(rcp->type)));
    669         fprintf(fp, LOCAL_PREFIX"L%s:\n", typelabel);
    670 
    671         fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n");        /* Flags */
    672         fprintf(fp, "\t"DIRECTIVE_LONG"\t"LONGFRMT"\n", (long)now);   /* TimeDate */
    673         fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n");    /* FIXME: must version be filled out? */
    674         fprintf(fp, "\t"DIRECTIVE_WORD"\t%d, %d\n", rcp->n_name_entries, rcp->n_id_entries);
    675         for(j = 0; j < rcp->count32; j++)
    676         {
    677             resource_t *rsc = rcp->rsc32array[j].rsc[0];
    678             /* NameId */
    679             if(rsc->name->type == name_ord)
    680                 fprintf(fp, "\t"DIRECTIVE_LONG"\t%d\n", rsc->name->name.i_name);
    681             else
    682             {
    683                 char *label = prep_nid_for_label(rsc->name);
    684                 fprintf(fp, "\t"DIRECTIVE_LONG"\t(%s_%d_%s_name - %s%s) "OR" "HEXBIT31"\n",
    685                     prefix,
    686                     rsc->type,
    687                     label,
    688                     prefix,
    689                     _PEResTab);
    690             }
    691             /* Maybe FIXME: Unescape the tree (ommit 0x80000000) and
    692              * put the offset to the resource data entry.
    693              * ?? Is unescaping worth while ??
    694              */
    695             /* Offset */
    696             namelabel = prep_nid_for_label(rsc->name);
    697             fprintf(fp, "\t"DIRECTIVE_LONG"\t("LOCAL_PREFIX"L%s_%s - %s%s) "OR" "HEXBIT31"\n",
    698                 typelabel,
    699                 namelabel,
    700                 prefix,
    701                 _PEResTab);
    702         }
    703         free(typelabel);
    704     }
    705 
    706     /* Write the language level of the tree */
    707 
    708     for(i = 0; i < rccount; i++)
    709     {
    710         res_count_t *rcp;
    711         char *namelabel;
    712         char *typelabel;
    713         int j;
    714 
    715         rcp = &rcarray[i];
    716         typelabel = xstrdup(prep_nid_for_label(&(rcp->type)));
    717 
    718         for(j = 0; j < rcp->count32; j++)
    719         {
    720             res32_count_t *r32cp = &(rcp->rsc32array[j]);
    721             int k;
    722 
    723             namelabel = xstrdup(prep_nid_for_label(r32cp->rsc[0]->name));
    724             fprintf(fp, LOCAL_PREFIX"L%s_%s:\n", typelabel, namelabel);
    725 
    726             fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n");        /* Flags */
    727             fprintf(fp, "\t"DIRECTIVE_LONG"\t"LONGFRMT"\n", (long)now);   /* TimeDate */
    728             fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n");    /* FIXME: must version be filled out? */
    729             fprintf(fp, "\t"DIRECTIVE_WORD"\t0, %d\n", r32cp->count);
    730 
    731             for(k = 0; k < r32cp->count; k++)
    732             {
    733                 resource_t *rsc = r32cp->rsc[k];
    734                 assert(rsc->lan != NULL);
    735                 /* LanguageId */
    736                 fprintf(fp, "\t"DIRECTIVE_LONG"\t"LONGFRMT"\n", rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0);
    737                 /* Offset */
    738                 fprintf(fp, "\t"DIRECTIVE_LONG"\t"LOCAL_PREFIX"L%s_%s_%d - %s%s\n",
    739                     typelabel,
    740                     namelabel,
    741                     rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0,
    742                     prefix,
    743                     _PEResTab);
    744             }
    745             free(namelabel);
    746         }
    747         free(typelabel);
    748     }
    749 
    750     /* Write the resource table itself */
    751     fprintf(fp, "%s_ResourceDirectory:\n", prefix);
    752     fprintf(fp, "\t"DIRECTIVE_GLOBAL"\t%s_ResourceDirectory\n", prefix);
    753     direntries = 0;
    754 
    755     for(i = 0; i < rccount; i++)
    756     {
    757         res_count_t *rcp;
    758         char *namelabel;
    759         char *typelabel;
    760         int j;
    761 
    762         rcp = &rcarray[i];
    763         typelabel = xstrdup(prep_nid_for_label(&(rcp->type)));
    764 
    765         for(j = 0; j < rcp->count32; j++)
    766         {
    767             res32_count_t *r32cp = &(rcp->rsc32array[j]);
    768             int k;
    769 
    770             namelabel = xstrdup(prep_nid_for_label(r32cp->rsc[0]->name));
    771 
    772             for(k = 0; k < r32cp->count; k++)
    773             {
    774                 resource_t *rsc = r32cp->rsc[k];
    775 
    776                 assert(rsc->lan != NULL);
    777 
    778                 fprintf(fp, LOCAL_PREFIX"L%s_%s_%d:\n",
    779                     typelabel,
    780                     namelabel,
    781                     rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0);
    782 
    783                 /* Data RVA */
    784                 fprintf(fp, "\t"DIRECTIVE_LONG"\t%s%s_data - %s%s\n",
    785                     prefix,
    786                     rsc->c_name,
    787                     prefix,
    788                     _PEResTab);
    789                 /* Size */
    790                 fprintf(fp, "\t"DIRECTIVE_LONG"\t%d\n",
    791                     rsc->binres->size - rsc->binres->dataidx);
    792                 /* CodePage */
    793                 fprintf(fp, "\t"DIRECTIVE_LONG"\t%ld\n", codepage);
    794                 /* Reserved */
    795                 fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n");
    796 
    797                 direntries++;
    798             }
    799             free(namelabel);
    800         }
    801         free(typelabel);
    802     }
     616        int i;
     617
     618        fprintf(fp, "\t%s\t4\n", DIRECTIVE_ALIGN);
     619        fprintf(fp, "%s%s:\n", prefix, _PEResTab);
     620        fprintf(fp, "\t%s\t%s%s\n", DIRECTIVE_GLOBAL, prefix, _PEResTab);
     621        /* Flags */
     622        fprintf(fp, "\t%s\t0\n", DIRECTIVE_LONG);
     623        /* Time/Date stamp */
     624        fprintf(fp, "\t%s\t"LONGFRMT"\n", DIRECTIVE_LONG, (long)now);
     625        /* Version */
     626        fprintf(fp, "\t%s\t0\n", DIRECTIVE_LONG);       /* FIXME: must version be filled out? */
     627        /* # of id entries, # of name entries */
     628        fprintf(fp, "\t%s\t%d, %d\n", DIRECTIVE_WORD, n_name_entries, n_id_entries);
     629
     630        /* Write the type level of the tree */
     631        for(i = 0; i < rccount; i++)
     632        {
     633                res_count_t *rcp;
     634                char *label;
     635
     636                rcp = &rcarray[i];
     637
     638                /* TypeId */
     639                if(rcp->type.type == name_ord)
     640                        fprintf(fp, "\t%s\t%d\n", DIRECTIVE_LONG, rcp->type.name.i_name);
     641                else
     642                {
     643                        char *name = prep_nid_for_label(&(rcp->type));
     644                        fprintf(fp, "\t%s\t(%s_%s_typename - %s%s) %s %s\n",
     645                                DIRECTIVE_LONG, prefix,
     646                                name,
     647                                prefix,
     648                                _PEResTab, OR, HEXBIT31);
     649                }
     650                /* Offset */
     651                label = prep_nid_for_label(&(rcp->type));
     652                fprintf(fp, "\t%s\t(%sL%s - %s%s) %s %s\n",
     653                        DIRECTIVE_LONG, LOCAL_PREFIX, label,
     654                        prefix,
     655                        _PEResTab, OR, HEXBIT31);
     656        }
     657
     658        /* Write the name level of the tree */
     659
     660        for(i = 0; i < rccount; i++)
     661        {
     662                res_count_t *rcp;
     663                char *typelabel;
     664                char *namelabel;
     665                int j;
     666
     667                rcp = &rcarray[i];
     668
     669                typelabel = xstrdup(prep_nid_for_label(&(rcp->type)));
     670                fprintf(fp, "%sL%s:\n", LOCAL_PREFIX, typelabel);
     671
     672                fprintf(fp, "\t%s\t0\n", DIRECTIVE_LONG);               /* Flags */
     673                fprintf(fp, "\t%s\t"LONGFRMT"\n", DIRECTIVE_LONG, (long)now);   /* TimeDate */
     674                fprintf(fp, "\t%s\t0\n", DIRECTIVE_LONG);       /* FIXME: must version be filled out? */
     675                fprintf(fp, "\t%s\t%d, %d\n", DIRECTIVE_WORD, rcp->n_name_entries, rcp->n_id_entries);
     676                for(j = 0; j < rcp->count32; j++)
     677                {
     678                        resource_t *rsc = rcp->rsc32array[j].rsc[0];
     679                        /* NameId */
     680                        if(rsc->name->type == name_ord)
     681                                fprintf(fp, "\t%s\t%d\n", DIRECTIVE_LONG, rsc->name->name.i_name);
     682                        else
     683                        {
     684                                fprintf(fp, "\t%s\t(%s%s_name - %s%s) %s %s\n",
     685                                        DIRECTIVE_LONG, prefix,
     686                                        rsc->c_name,
     687                                        prefix,
     688                                        _PEResTab, OR, HEXBIT31);
     689                        }
     690                        /* Maybe FIXME: Unescape the tree (ommit 0x80000000) and
     691                         * put the offset to the resource data entry.
     692                         * ?? Is unescaping worth while ??
     693                         */
     694                        /* Offset */
     695                        namelabel = prep_nid_for_label(rsc->name);
     696                        fprintf(fp, "\t%s\t(%sL%s_%s - %s%s) %s %s\n",
     697                                DIRECTIVE_LONG, LOCAL_PREFIX, typelabel,
     698                                namelabel,
     699                                prefix,
     700                                _PEResTab, OR, HEXBIT31);
     701                }
     702                free(typelabel);
     703        }
     704
     705        /* Write the language level of the tree */
     706
     707        for(i = 0; i < rccount; i++)
     708        {
     709                res_count_t *rcp;
     710                char *namelabel;
     711                char *typelabel;
     712                int j;
     713
     714                rcp = &rcarray[i];
     715                typelabel = xstrdup(prep_nid_for_label(&(rcp->type)));
     716
     717                for(j = 0; j < rcp->count32; j++)
     718                {
     719                        res32_count_t *r32cp = &(rcp->rsc32array[j]);
     720                        int k;
     721
     722                        namelabel = xstrdup(prep_nid_for_label(r32cp->rsc[0]->name));
     723                        fprintf(fp, "%sL%s_%s:\n", LOCAL_PREFIX, typelabel, namelabel);
     724
     725                        fprintf(fp, "\t%s\t0\n", DIRECTIVE_LONG);               /* Flags */
     726                        fprintf(fp, "\t%s\t"LONGFRMT"\n", DIRECTIVE_LONG, (long)now);   /* TimeDate */
     727                        fprintf(fp, "\t%s\t0\n", DIRECTIVE_LONG);       /* FIXME: must version be filled out? */
     728                        fprintf(fp, "\t%s\t0, %d\n", DIRECTIVE_WORD, r32cp->count);
     729
     730                        for(k = 0; k < r32cp->count; k++)
     731                        {
     732                                resource_t *rsc = r32cp->rsc[k];
     733                                assert(rsc->lan != NULL);
     734                                /* LanguageId */
     735                                fprintf(fp, "\t%s\t"LONGFRMT"\n", DIRECTIVE_LONG, rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0);
     736                                /* Offset */
     737                                fprintf(fp, "\t%s\t%sL%s_%s_%d - %s%s\n",
     738                                        DIRECTIVE_LONG, LOCAL_PREFIX, typelabel,
     739                                        namelabel,
     740                                        rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0,
     741                                        prefix,
     742                                        _PEResTab);
     743                        }
     744                        free(namelabel);
     745                }
     746                free(typelabel);
     747        }
     748
     749        /* Write the resource table itself */
     750        fprintf(fp, "%s_ResourceDirectory:\n", prefix);
     751        fprintf(fp, "\t%s\t%s_ResourceDirectory\n", DIRECTIVE_GLOBAL, prefix);
     752        direntries = 0;
     753
     754        for(i = 0; i < rccount; i++)
     755        {
     756                res_count_t *rcp;
     757                char *namelabel;
     758                char *typelabel;
     759                int j;
     760
     761                rcp = &rcarray[i];
     762                typelabel = xstrdup(prep_nid_for_label(&(rcp->type)));
     763
     764                for(j = 0; j < rcp->count32; j++)
     765                {
     766                        res32_count_t *r32cp = &(rcp->rsc32array[j]);
     767                        int k;
     768
     769                        namelabel = xstrdup(prep_nid_for_label(r32cp->rsc[0]->name));
     770
     771                        for(k = 0; k < r32cp->count; k++)
     772                        {
     773                                resource_t *rsc = r32cp->rsc[k];
     774
     775                                assert(rsc->lan != NULL);
     776
     777                                fprintf(fp, "%sL%s_%s_%d:\n",
     778                                        LOCAL_PREFIX, typelabel,
     779                                        namelabel,
     780                                        rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0);
     781
     782                                /* Data RVA */
     783                                fprintf(fp, "\t%s\t%s%s_data - %s%s\n",
     784                                        DIRECTIVE_LONG, prefix,
     785                                        rsc->c_name,
     786                                        prefix,
     787                                        _PEResTab);
     788                                /* Size */
     789                                fprintf(fp, "\t%s\t%d\n",
     790                                        DIRECTIVE_LONG, rsc->binres->size - rsc->binres->dataidx);
     791                                /* CodePage */
     792                                fprintf(fp, "\t%s\t%ld\n", DIRECTIVE_LONG, codepage);
     793                                /* Reserved */
     794                                fprintf(fp, "\t%s\t0\n", DIRECTIVE_LONG);
     795
     796                                direntries++;
     797                        }
     798                        free(namelabel);
     799                }
     800                free(typelabel);
     801        }
    803802}
    804803
    805804/*
    806805 *****************************************************************************
    807  * Function : write_ne_segment
    808  * Syntax   : void write_ne_segment(FILE *fp, resource_t *top)
    809  * Input    :
    810  * Output   :
    811  * Description  :
    812  * Remarks  :
     806 * Function     : write_ne_segment
     807 * Syntax       : void write_ne_segment(FILE *fp, resource_t *top)
     808 * Input        :
     809 * Output       :
     810 * Description  :
     811 * Remarks      :
    813812 *****************************************************************************
    814813*/
    815814void write_ne_segment(FILE *fp, resource_t *top)
    816815{
    817     int i, j;
    818 
    819     fprintf(fp, "\t"DIRECTIVE_ALIGN"\t4\n");
    820     fprintf(fp, "%s%s:\n", prefix, _NEResTab);
    821     fprintf(fp, "\t"DIRECTIVE_GLOBAL"\t%s%s\n", prefix, _NEResTab);
    822 
    823     /* AlignmentShift */
    824     fprintf(fp, "\t"DIRECTIVE_WORD"\t%d\n", alignment_pwr);
    825 
    826     /* TypeInfo */
    827     for(i = 0; i < rccount; i++)
    828     {
    829         res_count_t *rcp = &rcarray[i];
    830 
    831         /* TypeId */
    832         if(rcp->type.type == name_ord)
    833             fprintf(fp, "\t"DIRECTIVE_WORD"\t"SHORTFRMT"\n", rcp->type.name.i_name | 0x8000);
    834         else
    835             fprintf(fp, "\t"DIRECTIVE_WORD"\t%s_%s_typename - %s%s\n",
    836                 prefix,
    837                 rcp->type.name.s_name->str.cstr,
    838                 prefix,
    839                 _NEResTab);
    840         /* ResourceCount */
    841         fprintf(fp, "\t"DIRECTIVE_WORD"\t%d\n", rcp->count);
    842         /* Reserved */
    843         fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n");
    844         /* NameInfo */
    845         for(j = 0; j < rcp->count; j++)
    846         {
     816        int i, j;
     817
     818        fprintf(fp, "\t%s\t4\n", DIRECTIVE_ALIGN);
     819        fprintf(fp, "%s%s:\n", prefix, _NEResTab);
     820        fprintf(fp, "\t%s\t%s%s\n", DIRECTIVE_GLOBAL, prefix, _NEResTab);
     821
     822        /* AlignmentShift */
     823        fprintf(fp, "\t%s\t%d\n", DIRECTIVE_WORD, alignment_pwr);
     824
     825        /* TypeInfo */
     826        for(i = 0; i < rccount; i++)
     827        {
     828                res_count_t *rcp = &rcarray[i];
     829
     830                /* TypeId */
     831                if(rcp->type.type == name_ord)
     832                        fprintf(fp, "\t%s\t"SHORTFRMT"\n", DIRECTIVE_WORD, rcp->type.name.i_name | 0x8000);
     833                else
     834                        fprintf(fp, "\t%s\t%s_%s_typename - %s%s\n",
     835                                DIRECTIVE_WORD, prefix,
     836                                rcp->type.name.s_name->str.cstr,
     837                                prefix,
     838                                _NEResTab);
     839                /* ResourceCount */
     840                fprintf(fp, "\t%s\t%d\n", DIRECTIVE_WORD, rcp->count);
     841                /* Reserved */
     842                fprintf(fp, "\t%s\t0\n", DIRECTIVE_LONG);
     843                /* NameInfo */
     844                for(j = 0; j < rcp->count; j++)
     845                {
    847846/*
    848847 * VERY IMPORTANT:
     
    853852 * All other things are as the MS doc describes (alignment etc.)
    854853 */
    855             /* Offset */
    856             fprintf(fp, "\t"DIRECTIVE_WORD"\t(%s%s_data - %s%s) >> %d\n",
    857                 prefix,
    858                 rcp->rscarray[j]->c_name,
    859                 prefix,
    860                 _NEResTab,
    861                 alignment_pwr);
    862             /* Length */
    863             fprintf(fp, "\t"DIRECTIVE_WORD"\t%d\n",
    864                 rcp->rscarray[j]->binres->size - rcp->rscarray[j]->binres->dataidx);
    865             /* Flags */
    866             fprintf(fp, "\t"DIRECTIVE_WORD"\t"SHORTFRMT"\n", (WORD)rcp->rscarray[j]->memopt);
    867             /* Id */
    868             if(rcp->rscarray[j]->name->type == name_ord)
    869                 fprintf(fp, "\t"DIRECTIVE_WORD"\t"SHORTFRMT"\n", rcp->rscarray[j]->name->name.i_name | 0x8000);
    870             else
    871                 fprintf(fp, "\t"DIRECTIVE_WORD"\t%s%s_name - %s%s\n",
    872                 prefix,
    873                 rcp->rscarray[j]->c_name,
    874                 prefix,
    875                 _NEResTab);
    876             /* Handle and Usage */
    877             fprintf(fp, "\t"DIRECTIVE_WORD"\t0, 0\n");
    878         }
    879     }
    880     /* EndTypes */
    881     fprintf(fp, "\t"DIRECTIVE_WORD"\t0\n");
     854                        /* Offset */
     855                        fprintf(fp, "\t%s\t(%s%s_data - %s%s) >> %d\n",
     856                                DIRECTIVE_WORD, prefix,
     857                                rcp->rscarray[j]->c_name,
     858                                prefix,
     859                                _NEResTab,
     860                                alignment_pwr);
     861                        /* Length */
     862                        fprintf(fp, "\t%s\t%d\n",
     863                                DIRECTIVE_WORD, rcp->rscarray[j]->binres->size - rcp->rscarray[j]->binres->dataidx);
     864                        /* Flags */
     865                        fprintf(fp, "\t%s\t"SHORTFRMT"\n", DIRECTIVE_WORD, (WORD)rcp->rscarray[j]->memopt);
     866                        /* Id */
     867                        if(rcp->rscarray[j]->name->type == name_ord)
     868                                fprintf(fp, "\t%s\t"SHORTFRMT"\n", DIRECTIVE_WORD, rcp->rscarray[j]->name->name.i_name | 0x8000);
     869                        else
     870                                fprintf(fp, "\t%s\t%s%s_name - %s%s\n",
     871                                DIRECTIVE_WORD, prefix,
     872                                rcp->rscarray[j]->c_name,
     873                                prefix,
     874                                _NEResTab);
     875                        /* Handle and Usage */
     876                        fprintf(fp, "\t%s\t0, 0\n", DIRECTIVE_WORD);
     877                }
     878        }
     879        /* EndTypes */
     880        fprintf(fp, "\t%s\t0\n", DIRECTIVE_WORD);
    882881}
    883882
    884883/*
    885884 *****************************************************************************
    886  * Function : write_rsc_names
    887  * Syntax   : void write_rsc_names(FILE *fp, resource_t *top)
    888  * Input    :
    889  * Output   :
    890  * Description  :
    891  * Remarks  :
     885 * Function     : write_rsc_names
     886 * Syntax       : void write_rsc_names(FILE *fp, resource_t *top)
     887 * Input        :
     888 * Output       :
     889 * Description  :
     890 * Remarks      :
    892891 *****************************************************************************
    893892*/
    894893void write_rsc_names(FILE *fp, resource_t *top)
    895894{
    896     int i, j;
    897 
    898     if(win32)
    899     {
    900         /* Write the names */
    901 
    902         for(i = 0; i < rccount; i++)
    903         {
    904             res_count_t *rcp;
    905 
    906             rcp = &rcarray[i];
    907 
    908             if(rcp->type.type == name_str)
    909             {
    910                 char *name = prep_nid_for_label(&(rcp->type));
    911                 fprintf(fp, "%s_%s_typename:\n",
    912                     prefix,
    913                     name);
    914                 write_name_str(fp, &(rcp->type));
    915             }
    916 
    917             for(j = 0; j < rcp->count32; j++)
    918             {
    919                 resource_t *rsc = rcp->rsc32array[j].rsc[0];
    920 
    921                 if(rsc->name->type == name_str)
    922                 {
    923                     char *name = prep_nid_for_label(rsc->name);
    924 
    925                     fprintf(fp, "%s_%d_%s_name:\n",
    926                         prefix, rsc->type,
    927                         name);
    928                     write_name_str(fp, rsc->name);
    929                 }
    930             }
    931         }
    932     }
    933     else
    934     {
    935         /* ResourceNames */
    936         for(i = 0; i < rccount; i++)
    937         {
    938             res_count_t *rcp = &rcarray[i];
    939 
    940             for(j = 0; j < rcp->count; j++)
    941             {
    942                 if(rcp->type.type == name_str)
    943                 {
    944                     fprintf(fp, "%s_%s_typename:\n",
    945                         prefix,
    946                         rcp->type.name.s_name->str.cstr);
    947                     write_name_str(fp, &(rcp->type));
    948                 }
    949                 if(rcp->rscarray[j]->name->type == name_str)
    950                 {
    951                     fprintf(fp, "%s%s_name:\n",
    952                         prefix,
    953                         rcp->rscarray[j]->c_name);
    954                     write_name_str(fp, rcp->rscarray[j]->name);
    955                 }
    956             }
    957         }
    958         /* EndNames */
    959 
    960         /* This is to end the NE resource table */
    961         if(create_dir)
    962             fprintf(fp, "\t"DIRECTIVE_BYTE"\t0\n");
    963     }
    964 
    965     fprintf(fp, "\n");
     895        int i, j;
     896       
     897        if(win32)
     898        {
     899                /* Write the names */
     900
     901                for(i = 0; i < rccount; i++)
     902                {
     903                        res_count_t *rcp;
     904
     905                        rcp = &rcarray[i];
     906
     907                        if(rcp->type.type == name_str)
     908                        {
     909                                char *name = prep_nid_for_label(&(rcp->type));
     910                                fprintf(fp, "%s_%s_typename:\n",
     911                                        prefix,
     912                                        name);
     913                                write_name_str(fp, &(rcp->type));
     914                        }
     915
     916                        for(j = 0; j < rcp->count32; j++)
     917                        {
     918                                resource_t *rsc = rcp->rsc32array[j].rsc[0];
     919
     920                                if(rsc->name->type == name_str)
     921                                {
     922                                        fprintf(fp, "%s%s_name:\n",
     923                                                prefix,
     924                                                rsc->c_name);
     925                                        write_name_str(fp, rsc->name);
     926                                }
     927                        }
     928                }
     929        }
     930        else
     931        {
     932                /* ResourceNames */
     933                for(i = 0; i < rccount; i++)
     934                {
     935                        res_count_t *rcp = &rcarray[i];
     936
     937                        for(j = 0; j < rcp->count; j++)
     938                        {
     939                                if(rcp->type.type == name_str)
     940                                {
     941                                        fprintf(fp, "%s_%s_typename:\n",
     942                                                prefix,
     943                                                rcp->type.name.s_name->str.cstr);
     944                                        write_name_str(fp, &(rcp->type));
     945                                }
     946                                if(rcp->rscarray[j]->name->type == name_str)
     947                                {
     948                                        fprintf(fp, "%s%s_name:\n",
     949                                                prefix,
     950                                                rcp->rscarray[j]->c_name);
     951                                        write_name_str(fp, rcp->rscarray[j]->name);
     952                                }
     953                        }
     954                }
     955                /* EndNames */
     956               
     957                /* This is to end the NE resource table */
     958                if(create_dir)
     959                        fprintf(fp, "\t%s\t0\n", DIRECTIVE_BYTE);
     960        }
     961
     962        fprintf(fp, "\n");
    966963}
    967964
    968965/*
    969966 *****************************************************************************
    970  * Function : write_s_file
    971  * Syntax   : void write_s_file(char *outname, resource_t *top)
    972  * Input    :
    973  *  outname - Filename to write to
    974  *  top - The resource-tree to convert
    975  * Output   :
    976  * Description  :
    977  * Remarks  :
     967 * Function     : write_s_file
     968 * Syntax       : void write_s_file(char *outname, resource_t *top)
     969 * Input        :
     970 *      outname - Filename to write to
     971 *      top     - The resource-tree to convert
     972 * Output       :
     973 * Description  :
     974 * Remarks      :
    978975 *****************************************************************************
    979976*/
    980977void write_s_file(char *outname, resource_t *top)
    981978{
    982     FILE *fo;
    983     resource_t *rsc;
    984 
    985     fo = fopen(outname, "wt");
    986     if(!fo)
    987     {
    988         error("Could not open %s\n", outname);
    989         return;
    990     }
    991 
    992     {
    993         char *s, *p;
    994         now = time(NULL);
    995         s = ctime(&now);
    996         p = strchr(s, '\n');
    997         if(p) *p = '\0';
    998         fprintf(fo, s_file_head_str, input_name ? input_name : "stdin",
    999             cmdline, s);
    1000     }
    1001 
    1002     /* Get an idea how many we have and restructure the tables */
    1003     count_resources(top);
    1004 
    1005     /* First write the segment tables */
    1006     if(create_dir)
    1007     {
    1008         if(win32)
    1009             write_pe_segment(fo, top);
    1010         else
    1011             write_ne_segment(fo, top);
    1012     }
    1013 
    1014     /* Dump the names */
    1015     write_rsc_names(fo, top);
    1016 
    1017     if(create_dir)
    1018         fprintf(fo, LOCAL_PREFIX"LResTabEnd:\n");
    1019 
    1020     if(!indirect_only)
    1021     {
    1022         /* Write the resource data */
    1023             fprintf(fo, "\n"COMMENT_LINE"/* Resource binary data */\n\n");
    1024         for(rsc = top; rsc; rsc = rsc->next)
    1025         {
    1026             if(!rsc->binres)
    1027                 continue;
    1028 
    1029             fprintf(fo, "\t"DIRECTIVE_ALIGN"\t%d\n", win32 ? 4 : alignment);
    1030             fprintf(fo, "%s%s_data:\n", prefix, rsc->c_name);
    1031             if(global)
    1032                 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s%s_data\n", prefix, rsc->c_name);
    1033 
    1034             write_s_res(fo, rsc->binres);
    1035 
    1036             fprintf(fo, "\n");
    1037         }
    1038 
    1039         if(create_dir)
    1040         {
    1041             /* Add a resource descriptor for built-in and elf-dlls */
    1042             fprintf(fo, "\t"DIRECTIVE_ALIGN"\t4\n");
    1043             fprintf(fo, "%s_ResourceDescriptor:\n", prefix);
    1044             fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_ResourceDescriptor\n", prefix);
    1045             fprintf(fo, "%s_ResourceTable:\n", prefix);
    1046             if(global)
    1047                 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_ResourceTable\n", prefix);
    1048             fprintf(fo, "\t"DIRECTIVE_LONG"\t%s%s\n", prefix, win32 ? _PEResTab : _NEResTab);
    1049             fprintf(fo, "%s_NumberOfResources:\n", prefix);
    1050             if(global)
    1051                 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_NumberOfResources\n", prefix);
    1052             fprintf(fo, "\t"DIRECTIVE_LONG"\t%d\n", direntries);
    1053             fprintf(fo, "%s_ResourceSectionSize:\n", prefix);
    1054             if(global)
    1055                 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_ResourceSectionSize\n", prefix);
    1056             fprintf(fo, "\t"DIRECTIVE_LONG"\t"LOCAL_PREFIX"LResTabEnd - %s%s\n", prefix, win32 ? _PEResTab : _NEResTab);
    1057             if(win32)
    1058             {
    1059                 fprintf(fo, "%s_ResourcesEntries:\n", prefix);
    1060                 if(global)
    1061                     fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_ResourcesEntries\n", prefix);
    1062                 fprintf(fo, "\t"DIRECTIVE_LONG"\t%s_ResourceDirectory\n", prefix);
    1063             }
    1064         }
    1065     }
    1066 
    1067     if(indirect)
    1068     {
    1069         /* Write the indirection structures */
    1070         fprintf(fo, "\n"COMMENT_LINE"/* Resource indirection structures */\n\n");
    1071         fprintf(fo, "\t"DIRECTIVE_ALIGN"\t4\n");
    1072         for(rsc = top; rsc; rsc = rsc->next)
    1073         {
    1074             int type;
    1075             char *type_name = NULL;
    1076             char *label;
    1077 
    1078             if(!rsc->binres)
    1079                 continue;
    1080 
    1081             switch(rsc->type)
    1082             {
    1083             case res_menex:
    1084                 type = WRC_RT_MENU;
    1085                 break;
    1086             case res_dlgex:
    1087                 type = WRC_RT_DIALOG;
    1088                 break;
    1089             case res_usr:
    1090                 assert(rsc->res.usr->type != NULL);
    1091                 type_name = prep_nid_for_label(rsc->res.usr->type);
    1092                 type = 0;
    1093                 break;
    1094             default:
    1095                 type = rsc->type;
    1096             }
    1097 
    1098             /*
    1099              * This follows a structure like:
    1100              * struct wrc_resource {
    1101              *  INT32   id;
    1102              *  RSCNAME *resname;
    1103              *  INT32   restype;
    1104              *  RSCNAME *typename;
    1105              *  void    *data;
    1106              *  UINT32  datasize;
    1107              * };
    1108              * The 'RSCNAME' is a pascal-style string where the
    1109              * first byte/word denotes the size and the rest the string
    1110              * itself.
    1111              */
    1112             fprintf(fo, "%s%s:\n", prefix, rsc->c_name);
    1113             if(global)
    1114                 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s%s\n", prefix, rsc->c_name);
    1115             label = prep_nid_for_label(rsc->name);
    1116             fprintf(fo, "\t"DIRECTIVE_LONG"\t%d, %s%s%s%s, %d, %s%s%s%s, %s%s_data, %d\n",
    1117                 rsc->name->type == name_ord ? rsc->name->name.i_name : 0,
    1118                 rsc->name->type == name_ord ? "0" : prefix,
    1119                 rsc->name->type == name_ord ? "" : "_",
    1120                 rsc->name->type == name_ord ? "" : label,
    1121                 rsc->name->type == name_ord ? "" : "_name",
    1122                 type,
    1123                 type ? "0" : prefix,
    1124                 type ? "" : "_",
    1125                 type ? "" : type_name,
    1126                 type ? "" : "_typename",
    1127                 prefix,
    1128                 rsc->c_name,
    1129                 rsc->binres->size - rsc->binres->dataidx);
    1130             fprintf(fo, "\n");
    1131         }
    1132         fprintf(fo, "\n");
    1133 
    1134         /* Write the indirection table */
    1135         fprintf(fo, COMMENT_LINE"/* Resource indirection table */\n\n");
    1136         fprintf(fo, "\t"DIRECTIVE_ALIGN"\t4\n");
    1137         fprintf(fo, "%s%s:\n", prefix, _ResTable);
    1138         fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s%s\n", prefix, _ResTable);
    1139         for(rsc = top; rsc; rsc = rsc->next)
    1140         {
    1141             fprintf(fo, "\t"DIRECTIVE_LONG"\t%s%s\n", prefix, rsc->c_name);
    1142         }
    1143         fprintf(fo, "\t"DIRECTIVE_LONG"\t0\n");
    1144         fprintf(fo, "\n");
    1145     }
    1146 
    1147     if(auto_register)
    1148         fprintf(fo, s_file_autoreg_str, prefix, _ResTable);
    1149 
    1150     fprintf(fo, s_file_tail_str);
    1151     fclose(fo);
     979        FILE *fo;
     980        resource_t *rsc;
     981
     982        fo = fopen(outname, "wt");
     983        if(!fo)
     984        {
     985                error("Could not open %s\n", outname);
     986                return;
     987        }
     988
     989        {
     990                char *s, *p;
     991                now = time(NULL);
     992                s = ctime(&now);
     993                p = strchr(s, '\n');
     994                if(p) *p = '\0';
     995                fprintf(fo, s_file_head_str, input_name ? input_name : "stdin",
     996                        cmdline, s);
     997        }
     998
     999        /* Get an idea how many we have and restructure the tables */
     1000        count_resources(top);
     1001
     1002        /* First write the segment tables */
     1003        if(create_dir)
     1004        {
     1005                if(win32)
     1006                        write_pe_segment(fo, top);
     1007                else
     1008                        write_ne_segment(fo, top);
     1009        }
     1010
     1011        /* Dump the names */
     1012        write_rsc_names(fo, top);
     1013
     1014        if(create_dir)
     1015                fprintf(fo, "%sLResTabEnd:\n", LOCAL_PREFIX);
     1016       
     1017        if(!indirect_only)
     1018        {
     1019                /* Write the resource data */
     1020#ifdef MASM
     1021                fprintf(fo, "\n;/* Resource binary data */\n\n");
     1022#else
     1023                fprintf(fo, "\n/* Resource binary data */\n\n");
     1024#endif
     1025                for(rsc = top; rsc; rsc = rsc->next)
     1026                {
     1027                        if(!rsc->binres)
     1028                                continue;
     1029
     1030                        fprintf(fo, "\t%s\t%d\n", DIRECTIVE_ALIGN, win32 ? 4 : alignment);
     1031                        fprintf(fo, "%s%s_data:\n", prefix, rsc->c_name);
     1032                        if(global)
     1033                                fprintf(fo, "\t%s\t%s%s_data\n", DIRECTIVE_GLOBAL, prefix, rsc->c_name);
     1034
     1035                        write_s_res(fo, rsc->binres);
     1036
     1037                        fprintf(fo, "\n");
     1038                }
     1039
     1040                if(create_dir)
     1041                {
     1042                        /* Add a resource descriptor for built-in and elf-dlls */
     1043                        fprintf(fo, "\t%s\t4\n", DIRECTIVE_ALIGN);
     1044                        fprintf(fo, "%s_ResourceDescriptor:\n", prefix);
     1045                        fprintf(fo, "\t%s\t%s_ResourceDescriptor\n", DIRECTIVE_GLOBAL, prefix);
     1046                        fprintf(fo, "%s_ResourceTable:\n", prefix);
     1047                        if(global)
     1048                                fprintf(fo, "\t%s\t%s_ResourceTable\n", DIRECTIVE_GLOBAL, prefix);
     1049                        fprintf(fo, "\t%s\t%s%s\n", DIRECTIVE_LONG, prefix, win32 ? _PEResTab : _NEResTab);
     1050                        fprintf(fo, "%s_NumberOfResources:\n", prefix);
     1051                        if(global)
     1052                                fprintf(fo, "\t%s\t%s_NumberOfResources\n", DIRECTIVE_GLOBAL, prefix);
     1053                        fprintf(fo, "\t%s\t%d\n", DIRECTIVE_LONG, direntries);
     1054                        fprintf(fo, "%s_ResourceSectionSize:\n", prefix);
     1055                        if(global)
     1056                                fprintf(fo, "\t%s\t%s_ResourceSectionSize\n", DIRECTIVE_GLOBAL, prefix);
     1057                        fprintf(fo, "\t%s\t%sLResTabEnd - %s%s\n", DIRECTIVE_LONG, LOCAL_PREFIX, prefix, win32 ? _PEResTab : _NEResTab);
     1058                        if(win32)
     1059                        {
     1060                                fprintf(fo, "%s_ResourcesEntries:\n", prefix);
     1061                                if(global)
     1062                                        fprintf(fo, "\t%s\t%s_ResourcesEntries\n", DIRECTIVE_GLOBAL, prefix);
     1063                                fprintf(fo, "\t%s\t%s_ResourceDirectory\n", DIRECTIVE_LONG, prefix);
     1064                        }
     1065                }
     1066        }
     1067
     1068        if(indirect)
     1069        {
     1070                /* Write the indirection structures */
     1071                fprintf(fo, "\n/* Resource indirection structures */\n\n");
     1072                fprintf(fo, "\t%s\t4\n", DIRECTIVE_ALIGN);
     1073                for(rsc = top; rsc; rsc = rsc->next)
     1074                {
     1075                        int type;
     1076                        char *type_name = NULL;
     1077
     1078                        if(!rsc->binres)
     1079                                continue;
     1080
     1081                        switch(rsc->type)
     1082                        {
     1083                        case res_menex:
     1084                                type = WRC_RT_MENU;
     1085                                break;
     1086                        case res_dlgex:
     1087                                type = WRC_RT_DIALOG;
     1088                                break;
     1089                        case res_usr:
     1090                                assert(rsc->res.usr->type != NULL);
     1091                                type_name = prep_nid_for_label(rsc->res.usr->type);
     1092                                type = 0;
     1093                                break;
     1094                        default:
     1095                                type = rsc->type;
     1096                        }
     1097
     1098                        /*
     1099                         * This follows a structure like:
     1100                         * struct wrc_resource {
     1101                         *      INT32   id;
     1102                         *      RSCNAME *resname;
     1103                         *      INT32   restype;
     1104                         *      RSCNAME *typename;
     1105                         *      void    *data;
     1106                         *      UINT32  datasize;
     1107                         * };
     1108                         * The 'RSCNAME' is a pascal-style string where the
     1109                         * first byte/word denotes the size and the rest the string
     1110                         * itself.
     1111                         */
     1112                        fprintf(fo, "%s%s:\n", prefix, rsc->c_name);
     1113                        if(global)
     1114                                fprintf(fo, "\t%s\t%s%s\n", DIRECTIVE_GLOBAL, prefix, rsc->c_name);
     1115                        fprintf(fo, "\t%s\t%d, %s%s%s, %d, %s%s%s%s, %s%s_data, %d\n",
     1116                                DIRECTIVE_LONG,
     1117                                rsc->name->type == name_ord ? rsc->name->name.i_name : 0,
     1118                                rsc->name->type == name_ord ? "0" : prefix,
     1119                                rsc->name->type == name_ord ? "" : rsc->c_name,
     1120                                rsc->name->type == name_ord ? "" : "_name",
     1121                                type,
     1122                                type ? "0" : prefix,
     1123                                type ? "" : "_",
     1124                                type ? "" : type_name,
     1125                                type ? "" : "_typename",
     1126                                prefix,
     1127                                rsc->c_name,
     1128                                rsc->binres->size - rsc->binres->dataidx);
     1129                        fprintf(fo, "\n");
     1130                }
     1131                fprintf(fo, "\n");
     1132
     1133                /* Write the indirection table */
     1134                fprintf(fo, "/* Resource indirection table */\n\n");
     1135                fprintf(fo, "\t%s\t4\n", DIRECTIVE_ALIGN);
     1136                fprintf(fo, "%s%s:\n", prefix, _ResTable);
     1137                fprintf(fo, "\t%s\t%s%s\n", DIRECTIVE_GLOBAL, prefix, _ResTable);
     1138                for(rsc = top; rsc; rsc = rsc->next)
     1139                {
     1140                        fprintf(fo, "\t%s\t%s%s\n", DIRECTIVE_LONG, prefix, rsc->c_name);
     1141                }
     1142                fprintf(fo, "\t%s\t0\n", DIRECTIVE_LONG);
     1143                fprintf(fo, "\n");
     1144        }
     1145
     1146        if(auto_register)
     1147                fprintf(fo, s_file_autoreg_str, prefix, _ResTable);
     1148
     1149        fprintf(fo, s_file_tail_str);
     1150        fclose(fo);
    11521151}
    11531152
    11541153/*
    11551154 *****************************************************************************
    1156  * Function : write_h_file
    1157  * Syntax   : void write_h_file(char *outname, resource_t *top)
    1158  * Input    :
    1159  *  outname - Filename to write to
    1160  *  top - The resource-tree to convert
    1161  * Output   :
    1162  * Description  :
    1163  * Remarks  :
     1155 * Function     : write_h_file
     1156 * Syntax       : void write_h_file(char *outname, resource_t *top)
     1157 * Input        :
     1158 *      outname - Filename to write to
     1159 *      top     - The resource-tree to convert
     1160 * Output       :
     1161 * Description  :
     1162 * Remarks      :
    11641163 *****************************************************************************
    11651164*/
    11661165void write_h_file(char *outname, resource_t *top)
    11671166{
    1168     FILE *fo;
    1169     resource_t *rsc;
    1170     char *h_prefix;
     1167        FILE *fo;
     1168        resource_t *rsc;
     1169        char *h_prefix;
    11711170
    11721171#ifdef NEED_UNDERSCORE_PREFIX
    1173     h_prefix = prefix + 1;
     1172        h_prefix = prefix + 1;
    11741173#else
    1175     h_prefix = prefix;
     1174        h_prefix = prefix;
    11761175#endif
    11771176
    1178     fo = fopen(outname, "wt");
    1179     if(!fo)
    1180     {
    1181         error("Could not open %s\n", outname);
    1182     }
    1183 
    1184     time(&now);
    1185     fprintf(fo, h_file_head_str, input_name ? input_name : "stdin",
     1177        fo = fopen(outname, "wt");
     1178        if(!fo)
     1179        {
     1180                error("Could not open %s\n", outname);
     1181        }
     1182
     1183        time(&now);
     1184        fprintf(fo, h_file_head_str, input_name ? input_name : "stdin",
    11861185                cmdline, ctime(&now), (long)now, (long)now);
    11871186
    1188     /* First write the segment tables reference */
    1189     if(create_dir)
    1190     {
    1191         fprintf(fo, "extern %schar %s%s[];\n\n",
    1192             constant ? "const " : "",
    1193             h_prefix,
    1194             win32 ? _PEResTab : _NEResTab);
    1195     }
    1196 
    1197     /* Write the resource data */
    1198     for(rsc = top; global && rsc; rsc = rsc->next)
    1199     {
    1200         if(!rsc->binres)
    1201             continue;
    1202 
    1203         fprintf(fo, "extern %schar %s%s_data[];\n",
    1204             constant ? "const " : "",
    1205             h_prefix,
    1206             rsc->c_name);
    1207     }
    1208 
    1209     if(indirect)
    1210     {
    1211         if(global)
    1212             fprintf(fo, "\n");
    1213 
    1214         /* Write the indirection structures */
    1215         for(rsc = top; global && rsc; rsc = rsc->next)
    1216         {
    1217             fprintf(fo, "extern %swrc_resource%d_t %s%s;\n",
    1218                 constant ? "const " : "",
    1219                 win32 ? 32 : 16,
    1220                 h_prefix,
    1221                 rsc->c_name);
    1222         }
    1223 
    1224         if(global)
    1225             fprintf(fo, "\n");
    1226 
    1227         /* Write the indirection table */
    1228         fprintf(fo, "extern %swrc_resource%d_t %s%s[];\n\n",
    1229             constant ? "const " : "",
    1230             win32 ? 32 : 16,
    1231             h_prefix,
    1232             _ResTable);
    1233     }
    1234 
    1235     fprintf(fo, h_file_tail_str);
    1236     fclose(fo);
    1237 }
    1238 
    1239 
     1187        /* First write the segment tables reference */
     1188        if(create_dir)
     1189        {
     1190                fprintf(fo, "extern %schar %s%s[];\n\n",
     1191                        constant ? "const " : "",
     1192                        h_prefix,
     1193                        win32 ? _PEResTab : _NEResTab);
     1194        }
     1195
     1196        /* Write the resource data */
     1197        for(rsc = top; global && rsc; rsc = rsc->next)
     1198        {
     1199                if(!rsc->binres)
     1200                        continue;
     1201
     1202                fprintf(fo, "extern %schar %s%s_data[];\n",
     1203                        constant ? "const " : "",
     1204                        h_prefix,
     1205                        rsc->c_name);
     1206        }
     1207
     1208        if(indirect)
     1209        {
     1210                if(global)
     1211                        fprintf(fo, "\n");
     1212
     1213                /* Write the indirection structures */
     1214                for(rsc = top; global && rsc; rsc = rsc->next)
     1215                {
     1216                        fprintf(fo, "extern %swrc_resource%d_t %s%s;\n",
     1217                                constant ? "const " : "",
     1218                                win32 ? 32 : 16,
     1219                                h_prefix,
     1220                                rsc->c_name);
     1221                }
     1222
     1223                if(global)
     1224                        fprintf(fo, "\n");
     1225
     1226                /* Write the indirection table */
     1227                fprintf(fo, "extern %swrc_resource%d_t %s%s[];\n\n",
     1228                        constant ? "const " : "",
     1229                        win32 ? 32 : 16,
     1230                        h_prefix,
     1231                        _ResTable);
     1232        }
     1233
     1234        fprintf(fo, h_file_tail_str);
     1235        fclose(fo);
     1236}
     1237
     1238
Note: See TracChangeset for help on using the changeset viewer.