Ignore:
Timestamp:
Jun 26, 2001, 2:16:08 AM (24 years ago)
Author:
bird
Message:

EMX -> WIN32OS2, makeing fopen use w not wt. writeres.c

File:
1 edited

Legend:

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

    r5523 r6114  
    4646        "; Date   : %s */\n"
    4747        "\n"
    48         "\t.386p\n"
    49         "\t.model flat\n"
    50         "\t.data\n"
     48    "\t.386p\n"
     49    "\t.model flat\n"
     50    "\t.data\n"
    5151        "\n"
    52         ;
     52    ;
    5353
    5454static char s_file_tail_str[] =
    55         "\tend\n"
     55    "\tend\n"
    5656        "; <eof> */\n"
    5757        "\n"
    58         ;
     58    ;
    5959
    6060#else
     
    7878        "/* Date   : %s */\n"
    7979        "\n"
    80         "\t.data\n"
     80    "\t.data\n"
    8181        "\n"
    82         ;
     82    ;
    8383
    8484static char s_file_tail_str[] =
    8585        "/* <eof> */\n"
    8686        "\n"
    87         ;
     87    ;
    8888
    8989#endif
     
    9191
    9292static char s_file_autoreg_str[] =
    93         "\t.text\n"
    94         ".LAuto_Register:\n"
    95         "\tpushl\t$%s%s\n"
     93    "\t.text\n"
     94    ".LAuto_Register:\n"
     95    "\tpushl\t$%s%s\n"
    9696#ifdef NEED_UNDERSCORE_PREFIX
    97         "\tcall\t_LIBRES_RegisterResources\n"
     97    "\tcall\t_LIBRES_RegisterResources\n"
    9898#else
    99         "\tcall\tLIBRES_RegisterResources\n"
     99    "\tcall\tLIBRES_RegisterResources\n"
    100100#endif
    101         "\taddl\t$4,%%esp\n"
    102         "\tret\n\n"
     101    "\taddl\t$4,%%esp\n"
     102    "\tret\n\n"
    103103#ifdef __NetBSD__
    104         ".stabs \"___CTOR_LIST__\",22,0,0,.LAuto_Register\n\n"
     104    ".stabs \"___CTOR_LIST__\",22,0,0,.LAuto_Register\n\n"
    105105#else
    106         "\t.section .ctors,\"aw\"\n"
    107         "\t"DIRECTIVE_LONG"\t.LAuto_Register\n\n"
     106    "\t.section .ctors,\"aw\"\n"
     107    "\t"DIRECTIVE_LONG"\t.LAuto_Register\n\n"
    108108#endif
    109         ;
     109    ;
    110110
    111111static char h_file_head_str[] =
    112         "/*\n"
    113         " * This file is generated with wrc version " WRC_FULLVERSION ". Do not edit!\n"
    114         " * Source : %s\n"
    115         " * Cmdline: %s\n"
    116         " * Date   : %s"
    117         " */\n"
     112    "/*\n"
     113    " * This file is generated with wrc version " WRC_FULLVERSION ". Do not edit!\n"
     114    " * Source : %s\n"
     115    " * Cmdline: %s\n"
     116    " * Date   : %s"
     117    " */\n"
    118118        "\n"
    119         "#ifndef __%08lx_H\n"   /* This becomes the date of compile */
    120         "#define __%08lx_H\n"
    121         "\n"
    122         "#include <wrc_rsc.h>\n"
    123         "\n"
    124         ;
     119    "#ifndef __%08lx_H\n"   /* This becomes the date of compile */
     120    "#define __%08lx_H\n"
     121    "\n"
     122    "#include <wrc_rsc.h>\n"
     123    "\n"
     124    ;
    125125
    126126static char h_file_tail_str[] =
    127         "#endif\n"
    128         "/* <eof> */\n\n"
    129         ;
     127    "#endif\n"
     128    "/* <eof> */\n\n"
     129    ;
    130130
    131131char _NEResTab[] = "_NEResTab";
     
    134134
    135135/* Variables used for resource sorting */
    136 res_count_t *rcarray = NULL;    /* Type-level count array */
    137 int rccount = 0;                /* Nr of entries in the type-level array */
    138 int n_id_entries = 0;           /* win32 only: Nr of unique ids in the type-level array */
    139 int n_name_entries = 0;         /* win32 only: Nr of unique namess in the type-level array */
    140 
    141 static int direntries;          /* win32 only: Total number of unique resources */
     136res_count_t *rcarray = NULL;    /* Type-level count array */
     137int rccount = 0;        /* Nr of entries in the type-level array */
     138int n_id_entries = 0;       /* win32 only: Nr of unique ids in the type-level array */
     139int n_name_entries = 0;     /* win32 only: Nr of unique namess in the type-level array */
     140
     141static int direntries;      /* win32 only: Total number of unique resources */
    142142
    143143/*
    144144 *****************************************************************************
    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      :
     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  :
    153153 *****************************************************************************
    154154*/
    155155void write_resfile(char *outname, resource_t *top)
    156156{
    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);
     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);
    214214}
    215215
    216216/*
    217217 *****************************************************************************
    218  * Function     : write_s_res
    219  * Syntax       : void write_s_res(FILE *fp, res_t *res)
    220  * Input        :
    221  * Output       :
    222  * Description  :
    223  * Remarks      :
     218 * Function : write_s_res
     219 * Syntax   : void write_s_res(FILE *fp, res_t *res)
     220 * Input    :
     221 * Output   :
     222 * Description  :
     223 * Remarks  :
    224224 *****************************************************************************
    225225*/
    226 #define BYTESPERLINE    8
     226#define BYTESPERLINE    8
    227227static void write_s_res(FILE *fp, res_t *res)
    228228{
    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         }
     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    }
    255255}
    256256#undef BYTESPERLINE
     
    258258/*
    259259 *****************************************************************************
    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
     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
    266266 *****************************************************************************
    267267*/
    268268static void write_name_str(FILE *fp, name_id_t *nid)
    269269{
    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 length 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 = strlenW(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                 strcpyW((WCHAR *)(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         }
     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 length 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 = strlenW(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        strcpyW((WCHAR *)(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    }
    333333}
    334334
    335335/*
    336336 *****************************************************************************
    337  * Function     : find_counter
    338  * Syntax       : res_count_t *find_counter(name_id_t *type)
    339  * Input        :
    340  * Output       :
    341  * Description  :
    342  * Remarks      :
     337 * Function : find_counter
     338 * Syntax   : res_count_t *find_counter(name_id_t *type)
     339 * Input    :
     340 * Output   :
     341 * Description  :
     342 * Remarks  :
    343343 *****************************************************************************
    344344*/
    345345static res_count_t *find_counter(name_id_t *type)
    346346{
    347         int i;
    348         for(i = 0; i < rccount; i++)
    349         {
    350                 if(!compare_name_id(type, &(rcarray[i].type)))
    351                         return &rcarray[i];
    352         }
    353         return NULL;
     347    int i;
     348    for(i = 0; i < rccount; i++)
     349    {
     350        if(!compare_name_id(type, &(rcarray[i].type)))
     351            return &rcarray[i];
     352    }
     353    return NULL;
    354354}
    355355
    356356/*
    357357 *****************************************************************************
    358  * Function     : count_resources
    359  * Syntax       : res_count_t *count_resources(resource_t *top)
    360  * Input        :
    361  * Output       :
    362  * Description  :
    363  * Remarks      : The whole lot is converted into arrays because they are
    364  *                easy sortable. Makes the lot almost unreadable, but it
    365  *                works (I hope). Basically you have to keep in mind that
    366  *                the lot is a three-dimensional structure for win32 and a
    367  *                two-dimensional structure for win16.
     358 * Function : count_resources
     359 * Syntax   : res_count_t *count_resources(resource_t *top)
     360 * Input    :
     361 * Output   :
     362 * Description  :
     363 * Remarks  : The whole lot is converted into arrays because they are
     364 *        easy sortable. Makes the lot almost unreadable, but it
     365 *        works (I hope). Basically you have to keep in mind that
     366 *        the lot is a three-dimensional structure for win32 and a
     367 *        two-dimensional structure for win16.
    368368 *****************************************************************************
    369369*/
    370 #define RCT(v)  (*((resource_t **)(v)))
     370#define RCT(v)  (*((resource_t **)(v)))
    371371/* qsort sorting function */
    372372static int sort_name_id(const void *e1, const void *e2)
    373373{
    374         return compare_name_id(RCT(e1)->name, RCT(e2)->name);
     374    return compare_name_id(RCT(e1)->name, RCT(e2)->name);
    375375}
    376376
    377377static int sort_language(const void *e1, const void *e2)
    378378{
    379         assert((RCT(e1)->lan) != NULL);
    380         assert((RCT(e2)->lan) != NULL);
    381 
    382         return MAKELANGID(RCT(e1)->lan->id, RCT(e1)->lan->sub)
    383              - MAKELANGID(RCT(e2)->lan->id, RCT(e2)->lan->sub);
     379    assert((RCT(e1)->lan) != NULL);
     380    assert((RCT(e2)->lan) != NULL);
     381
     382    return MAKELANGID(RCT(e1)->lan->id, RCT(e1)->lan->sub)
     383         - MAKELANGID(RCT(e2)->lan->id, RCT(e2)->lan->sub);
    384384}
    385385#undef RCT
    386 #define RCT(v)  ((res_count_t *)(v))
     386#define RCT(v)  ((res_count_t *)(v))
    387387static int sort_type(const void *e1, const void *e2)
    388388{
    389         return compare_name_id(&(RCT(e1)->type), &(RCT(e2)->type));
     389    return compare_name_id(&(RCT(e1)->type), &(RCT(e2)->type));
    390390}
    391391#undef RCT
     
    393393static void count_resources(resource_t *top)
    394394{
    395         resource_t *rsc;
    396         res_count_t *rcp;
    397         name_id_t nid;
    398         int i, j;
    399 
    400         for(rsc = top; rsc; rsc = rsc->next)
    401         {
    402                 if(!rsc->binres)
    403                         continue;
    404                 switch(rsc->type)
    405                 {
    406                 case res_dlgex:
    407                         nid.name.i_name = WRC_RT_DIALOG;
    408                         nid.type = name_ord;
    409                         break;
    410                 case res_menex:
    411                         nid.name.i_name = WRC_RT_MENU;
    412                         nid.type = name_ord;
    413                         break;
    414                 case res_usr:
    415                         nid = *(rsc->res.usr->type);
    416                         break;
    417                 default:
    418                         nid.name.i_name = rsc->type;
    419                         nid.type = name_ord;
    420                 }
    421 
    422                 if((rcp = find_counter(&nid)) == NULL)
    423                 {
    424                         /* Count the number of uniq ids and names */
    425 
    426                         if(nid.type == name_ord)
    427                                 n_id_entries++;
    428                         else
    429                                 n_name_entries++;
    430 
    431                         if(!rcarray)
    432                         {
    433                                 rcarray = (res_count_t *)xmalloc(sizeof(res_count_t));
    434                                 rccount = 1;
    435                                 rcarray[0].count = 1;
    436                                 rcarray[0].type = nid;
    437                                 rcarray[0].rscarray = (resource_t **)xmalloc(sizeof(resource_t *));
    438                                 rcarray[0].rscarray[0] = rsc;
    439                         }
    440                         else
    441                         {
    442                                 rccount++;
    443                                 rcarray = (res_count_t *)xrealloc(rcarray, rccount * sizeof(res_count_t));
    444                                 rcarray[rccount-1].count = 1;
    445                                 rcarray[rccount-1].type = nid;
    446                                 rcarray[rccount-1].rscarray = (resource_t **)xmalloc(sizeof(resource_t *));
    447                                 rcarray[rccount-1].rscarray[0] = rsc;
    448                         }
    449                 }
    450                 else
    451                 {
    452                         rcp->count++;
    453                         rcp->rscarray = (resource_t **)xrealloc(rcp->rscarray, rcp->count * sizeof(resource_t *));
    454                         rcp->rscarray[rcp->count-1] = rsc;
    455                 }
    456         }
    457 
    458         if(!win32)
    459         {
    460                 /* We're done, win16 requires no special sorting */
    461                 return;
    462         }
    463 
    464         /* We now have a unsorted list of types with an array of res_count_t
    465         * in rcarray[0..rccount-1]. And we have names of one type in the
    466         * rcarray[x].rsc[0..rcarray[x].count-1] arrays.
    467         * The list needs to be sorted for win32's top level tree structure.
    468         */
    469 
    470         /* Sort the types */
    471         if(rccount > 1)
    472                 qsort(rcarray, rccount, sizeof(rcarray[0]), sort_type);
    473 
    474         /* Now sort the name-id arrays */
    475         for(i = 0; i < rccount; i++)
    476         {
    477                 if(rcarray[i].count > 1)
    478                         qsort(rcarray[i].rscarray, rcarray[i].count, sizeof(rcarray[0].rscarray[0]), sort_name_id);
    479         }
    480 
    481         /* Now split the name-id arrays into name/language
    482         * subs. Don't look at the awfull expressions...
    483         * We do this by taking the array elements out of rscarray and putting
    484         * together a new array in rsc32array.
    485         */
    486         for(i = 0; i < rccount; i++)
    487         {
    488                 res_count_t *rcap;
    489 
    490                 assert(rcarray[i].count >= 1);
    491 
    492                 /* rcap points to the current type we are dealing with */
    493                 rcap = &(rcarray[i]);
    494 
    495                 /* Insert the first name-id */
    496                 rcap->rsc32array = (res32_count_t *)xmalloc(sizeof(res32_count_t));
    497                 rcap->count32 = 1;
    498                 rcap->rsc32array[0].rsc = (resource_t **)xmalloc(sizeof(resource_t *));
    499                 rcap->rsc32array[0].count = 1;
    500                 rcap->rsc32array[0].rsc[0] = rcap->rscarray[0];
    501                 if(rcap->rscarray[0]->name->type == name_ord)
    502                 {
    503                         rcap->n_id_entries = 1;
    504                         rcap->n_name_entries = 0;
    505                 }
    506                 else
    507                 {
    508                         rcap->n_id_entries = 0;
    509                         rcap->n_name_entries = 1;
    510                 }
    511 
    512                 /* Now loop over the resting resources of the current type
    513                 * to find duplicate names (which should have different
    514                 * languages).
    515                 */
    516                 for(j = 1; j < rcap->count; j++)
    517                 {
    518                         res32_count_t *r32cp;
    519 
    520                         /* r32cp points to the current res32_count structure
    521                         * that holds the resource name we are processing.
    522                         */
    523                         r32cp = &(rcap->rsc32array[rcap->count32-1]);
    524 
    525                         if(!compare_name_id(r32cp->rsc[0]->name, rcarray[i].rscarray[j]->name))
    526                         {
    527                                 /* Names are the same, add to list */
    528                                 r32cp->count++;
    529                                 r32cp->rsc = (resource_t **)xrealloc(r32cp->rsc, r32cp->count * sizeof(resource_t *));
    530                                 r32cp->rsc[r32cp->count-1] = rcap->rscarray[j];
    531                         }
    532                         else
    533                         {
    534                                 /* New name-id, sort the old one by
    535                                 * language and create new list
    536                                 */
    537                                 if(r32cp->count > 1)
    538                                         qsort(r32cp->rsc, r32cp->count, sizeof(r32cp->rsc[0]), sort_language);
    539                                 rcap->count32++;
    540                                 rcap->rsc32array = (res32_count_t*)xrealloc(rcap->rsc32array, rcap->count32 * sizeof(res32_count_t));
    541                                 rcap->rsc32array[rcap->count32-1].rsc = (resource_t **)xmalloc(sizeof(resource_t *));
    542                                 rcap->rsc32array[rcap->count32-1].count = 1;
    543                                 rcap->rsc32array[rcap->count32-1].rsc[0] = rcap->rscarray[j];
    544 
    545                                 if(rcap->rscarray[j]->name->type == name_ord)
    546                                         rcap->n_id_entries++;
    547                                 else
    548                                         rcap->n_name_entries++;
    549                         }
    550                 }
    551                 /* Also sort the languages of the last name group */
    552                 if(rcap->rsc32array[rcap->count32-1].count > 1)
    553                         qsort(rcap->rsc32array[rcap->count32-1].rsc,
    554                               rcap->rsc32array[rcap->count32-1].count,
    555                               sizeof(rcap->rsc32array[rcap->count32-1].rsc[0]),
    556                               sort_language);
    557         }
     395    resource_t *rsc;
     396    res_count_t *rcp;
     397    name_id_t nid;
     398    int i, j;
     399
     400    for(rsc = top; rsc; rsc = rsc->next)
     401    {
     402        if(!rsc->binres)
     403            continue;
     404        switch(rsc->type)
     405        {
     406        case res_dlgex:
     407            nid.name.i_name = WRC_RT_DIALOG;
     408            nid.type = name_ord;
     409            break;
     410        case res_menex:
     411            nid.name.i_name = WRC_RT_MENU;
     412            nid.type = name_ord;
     413            break;
     414        case res_usr:
     415            nid = *(rsc->res.usr->type);
     416            break;
     417        default:
     418            nid.name.i_name = rsc->type;
     419            nid.type = name_ord;
     420        }
     421
     422        if((rcp = find_counter(&nid)) == NULL)
     423        {
     424            /* Count the number of uniq ids and names */
     425
     426            if(nid.type == name_ord)
     427                n_id_entries++;
     428            else
     429                n_name_entries++;
     430
     431            if(!rcarray)
     432            {
     433                rcarray = (res_count_t *)xmalloc(sizeof(res_count_t));
     434                rccount = 1;
     435                rcarray[0].count = 1;
     436                rcarray[0].type = nid;
     437                rcarray[0].rscarray = (resource_t **)xmalloc(sizeof(resource_t *));
     438                rcarray[0].rscarray[0] = rsc;
     439            }
     440            else
     441            {
     442                rccount++;
     443                rcarray = (res_count_t *)xrealloc(rcarray, rccount * sizeof(res_count_t));
     444                rcarray[rccount-1].count = 1;
     445                rcarray[rccount-1].type = nid;
     446                rcarray[rccount-1].rscarray = (resource_t **)xmalloc(sizeof(resource_t *));
     447                rcarray[rccount-1].rscarray[0] = rsc;
     448            }
     449        }
     450        else
     451        {
     452            rcp->count++;
     453            rcp->rscarray = (resource_t **)xrealloc(rcp->rscarray, rcp->count * sizeof(resource_t *));
     454            rcp->rscarray[rcp->count-1] = rsc;
     455        }
     456    }
     457
     458    if(!win32)
     459    {
     460        /* We're done, win16 requires no special sorting */
     461        return;
     462    }
     463
     464    /* We now have a unsorted list of types with an array of res_count_t
     465    * in rcarray[0..rccount-1]. And we have names of one type in the
     466    * rcarray[x].rsc[0..rcarray[x].count-1] arrays.
     467    * The list needs to be sorted for win32's top level tree structure.
     468    */
     469
     470    /* Sort the types */
     471    if(rccount > 1)
     472        qsort(rcarray, rccount, sizeof(rcarray[0]), sort_type);
     473
     474    /* Now sort the name-id arrays */
     475    for(i = 0; i < rccount; i++)
     476    {
     477        if(rcarray[i].count > 1)
     478            qsort(rcarray[i].rscarray, rcarray[i].count, sizeof(rcarray[0].rscarray[0]), sort_name_id);
     479    }
     480
     481    /* Now split the name-id arrays into name/language
     482    * subs. Don't look at the awfull expressions...
     483    * We do this by taking the array elements out of rscarray and putting
     484    * together a new array in rsc32array.
     485    */
     486    for(i = 0; i < rccount; i++)
     487    {
     488        res_count_t *rcap;
     489
     490        assert(rcarray[i].count >= 1);
     491
     492        /* rcap points to the current type we are dealing with */
     493        rcap = &(rcarray[i]);
     494
     495        /* Insert the first name-id */
     496        rcap->rsc32array = (res32_count_t *)xmalloc(sizeof(res32_count_t));
     497        rcap->count32 = 1;
     498        rcap->rsc32array[0].rsc = (resource_t **)xmalloc(sizeof(resource_t *));
     499        rcap->rsc32array[0].count = 1;
     500        rcap->rsc32array[0].rsc[0] = rcap->rscarray[0];
     501        if(rcap->rscarray[0]->name->type == name_ord)
     502        {
     503            rcap->n_id_entries = 1;
     504            rcap->n_name_entries = 0;
     505        }
     506        else
     507        {
     508            rcap->n_id_entries = 0;
     509            rcap->n_name_entries = 1;
     510        }
     511
     512        /* Now loop over the resting resources of the current type
     513        * to find duplicate names (which should have different
     514        * languages).
     515        */
     516        for(j = 1; j < rcap->count; j++)
     517        {
     518            res32_count_t *r32cp;
     519
     520            /* r32cp points to the current res32_count structure
     521            * that holds the resource name we are processing.
     522            */
     523            r32cp = &(rcap->rsc32array[rcap->count32-1]);
     524
     525            if(!compare_name_id(r32cp->rsc[0]->name, rcarray[i].rscarray[j]->name))
     526            {
     527                /* Names are the same, add to list */
     528                r32cp->count++;
     529                r32cp->rsc = (resource_t **)xrealloc(r32cp->rsc, r32cp->count * sizeof(resource_t *));
     530                r32cp->rsc[r32cp->count-1] = rcap->rscarray[j];
     531            }
     532            else
     533            {
     534                /* New name-id, sort the old one by
     535                * language and create new list
     536                */
     537                if(r32cp->count > 1)
     538                    qsort(r32cp->rsc, r32cp->count, sizeof(r32cp->rsc[0]), sort_language);
     539                rcap->count32++;
     540                rcap->rsc32array = (res32_count_t*)xrealloc(rcap->rsc32array, rcap->count32 * sizeof(res32_count_t));
     541                rcap->rsc32array[rcap->count32-1].rsc = (resource_t **)xmalloc(sizeof(resource_t *));
     542                rcap->rsc32array[rcap->count32-1].count = 1;
     543                rcap->rsc32array[rcap->count32-1].rsc[0] = rcap->rscarray[j];
     544
     545                if(rcap->rscarray[j]->name->type == name_ord)
     546                    rcap->n_id_entries++;
     547                else
     548                    rcap->n_name_entries++;
     549            }
     550        }
     551        /* Also sort the languages of the last name group */
     552        if(rcap->rsc32array[rcap->count32-1].count > 1)
     553            qsort(rcap->rsc32array[rcap->count32-1].rsc,
     554                  rcap->rsc32array[rcap->count32-1].count,
     555                  sizeof(rcap->rsc32array[rcap->count32-1].rsc[0]),
     556                  sort_language);
     557    }
    558558}
    559559
    560560/*
    561561 *****************************************************************************
    562  * Function     : write_pe_segment
    563  * Syntax       : void write_pe_segment(FILE *fp)
    564  * Input        :
    565  * Output       :
    566  * Description  :
    567  * Remarks      :
     562 * Function : write_pe_segment
     563 * Syntax   : void write_pe_segment(FILE *fp)
     564 * Input    :
     565 * Output   :
     566 * Description  :
     567 * Remarks  :
    568568 *****************************************************************************
    569569*/
    570570static void write_pe_segment(FILE *fp)
    571571{
    572         int i;
    573 
    574         fprintf(fp, "\t"DIRECTIVE_ALIGN"\t4\n");
    575         fprintf(fp, "%s%s:\n", prefix, _PEResTab);
    576         fprintf(fp, "\t"DIRECTIVE_GLOBAL"\t%s%s\n", prefix, _PEResTab);
    577         /* Flags */
    578         fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n");
    579         /* Time/Date stamp */
    580         fprintf(fp, "\t"DIRECTIVE_LONG"\t"LONGFRMT"\n", (long)now);
    581         /* Version */
    582         fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n"); /* FIXME: must version be filled out? */
    583         /* # of id entries, # of name entries */
    584         fprintf(fp, "\t"DIRECTIVE_SHORT"\t%d, %d\n", n_name_entries, n_id_entries);
    585 
    586         /* Write the type level of the tree */
    587         for(i = 0; i < rccount; i++)
    588         {
    589                 res_count_t *rcp;
    590                 char *label;
    591 
    592                 rcp = &rcarray[i];
    593 
    594                 /* TypeId */
    595                 if(rcp->type.type == name_ord)
    596                         fprintf(fp, "\t"DIRECTIVE_LONG"\t%d\n", rcp->type.name.i_name);
    597                 else
    598                 {
    599                         char *name = prep_nid_for_label(&(rcp->type));
    600                         fprintf(fp, "\t"DIRECTIVE_LONG"\t(%s_%s_typename - %s%s) "OR" "HEXBIT31"\n",
    601                                 prefix,
    602                                 name,
    603                                 prefix,
    604                                 _PEResTab);
    605                 }
    606                 /* Offset */
    607                 label = prep_nid_for_label(&(rcp->type));
    608                 fprintf(fp, "\t"DIRECTIVE_LONG"\t("LOCAL_PREFIX"L%s - %s%s) "OR" "HEXBIT31"\n",
    609                         label,
    610                         prefix,
    611                         _PEResTab);
    612         }
    613 
    614         /* Write the name level of the tree */
    615 
    616         for(i = 0; i < rccount; i++)
    617         {
    618                 res_count_t *rcp;
    619                 char *typelabel;
    620                 char *namelabel;
    621                 int j;
    622 
    623                 rcp = &rcarray[i];
    624 
    625                 typelabel = xstrdup(prep_nid_for_label(&(rcp->type)));
    626                 fprintf(fp, ""LOCAL_PREFIX"L%s:\n", typelabel);
    627 
    628                 fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n");         /* Flags */
    629                 fprintf(fp, "\t"DIRECTIVE_LONG"\t"LONGFRMT"\n", (long)now);     /* TimeDate */
    630                 fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n"); /* FIXME: must version be filled out? */
    631                 fprintf(fp, "\t"DIRECTIVE_SHORT"\t%d, %d\n", rcp->n_name_entries, rcp->n_id_entries);
    632                 for(j = 0; j < rcp->count32; j++)
    633                 {
    634                         resource_t *rsc = rcp->rsc32array[j].rsc[0];
    635                         /* NameId */
    636                         if(rsc->name->type == name_ord)
    637                                 fprintf(fp, "\t"DIRECTIVE_LONG"\t%d\n", rsc->name->name.i_name);
    638                         else
    639                         {
    640                                 fprintf(fp, "\t"DIRECTIVE_LONG"\t(%s%s_name - %s%s) "OR" "HEXBIT31"\n",
    641                                         prefix,
    642                                         rsc->c_name,
    643                                         prefix,
    644                                         _PEResTab);
    645                         }
    646                         /* Maybe FIXME: Unescape the tree (ommit "HEXBIT31") and
    647                         * put the offset to the resource data entry.
    648                         * ?? Is unescaping worth while ??
    649                         */
    650                         /* Offset */
    651                         namelabel = prep_nid_for_label(rsc->name);
    652                         fprintf(fp, "\t"DIRECTIVE_LONG"\t("LOCAL_PREFIX"L%s_%s - %s%s) "OR" "HEXBIT31"\n",
    653                                 typelabel,
    654                                 namelabel,
    655                                 prefix,
    656                                 _PEResTab);
    657                 }
    658                 free(typelabel);
    659         }
    660 
    661         /* Write the language level of the tree */
    662 
    663         for(i = 0; i < rccount; i++)
    664         {
    665                 res_count_t *rcp;
    666                 char *namelabel;
    667                 char *typelabel;
    668                 int j;
    669 
    670                 rcp = &rcarray[i];
    671                 typelabel = xstrdup(prep_nid_for_label(&(rcp->type)));
    672 
    673                 for(j = 0; j < rcp->count32; j++)
    674                 {
    675                         res32_count_t *r32cp = &(rcp->rsc32array[j]);
    676                         int k;
    677 
    678                         namelabel = xstrdup(prep_nid_for_label(r32cp->rsc[0]->name));
    679                         fprintf(fp, ""LOCAL_PREFIX"L%s_%s:\n", typelabel, namelabel);
    680 
    681                         fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n");         /* Flags */
    682                         fprintf(fp, "\t"DIRECTIVE_LONG"\t"LONGFRMT"\n", (long)now);     /* TimeDate */
    683                         fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n"); /* FIXME: must version be filled out? */
    684                         fprintf(fp, "\t"DIRECTIVE_SHORT"\t0, %d\n", r32cp->count);
    685 
    686                         for(k = 0; k < r32cp->count; k++)
    687                         {
    688                                 resource_t *rsc = r32cp->rsc[k];
    689                                 assert(rsc->lan != NULL);
    690                                 /* LanguageId */
    691                                 fprintf(fp, "\t"DIRECTIVE_LONG"\t"LONGFRMT"\n", rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0);
    692                                 /* Offset */
    693                                 fprintf(fp, "\t"DIRECTIVE_LONG"\t"LOCAL_PREFIX"L%s_%s_%d - %s%s\n",
    694                                         typelabel,
    695                                         namelabel,
    696                                         rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0,
    697                                         prefix,
    698                                         _PEResTab);
    699                         }
    700                         free(namelabel);
    701                 }
    702                 free(typelabel);
    703         }
    704 
    705         /* Write the resource table itself */
    706         fprintf(fp, "%s_ResourceDirectory:\n", prefix);
    707         fprintf(fp, "\t"DIRECTIVE_GLOBAL"\t%s_ResourceDirectory\n", prefix);
    708         direntries = 0;
    709 
    710         for(i = 0; i < rccount; i++)
    711         {
    712                 res_count_t *rcp;
    713                 char *namelabel;
    714                 char *typelabel;
    715                 int j;
    716 
    717                 rcp = &rcarray[i];
    718                 typelabel = xstrdup(prep_nid_for_label(&(rcp->type)));
    719 
    720                 for(j = 0; j < rcp->count32; j++)
    721                 {
    722                         res32_count_t *r32cp = &(rcp->rsc32array[j]);
    723                         int k;
    724 
    725                         namelabel = xstrdup(prep_nid_for_label(r32cp->rsc[0]->name));
    726 
    727                         for(k = 0; k < r32cp->count; k++)
    728                         {
    729                                 resource_t *rsc = r32cp->rsc[k];
    730 
    731                                 assert(rsc->lan != NULL);
    732 
    733                                 fprintf(fp, ""LOCAL_PREFIX"L%s_%s_%d:\n",
    734                                         typelabel,
    735                                         namelabel,
    736                                         rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0);
    737 
    738                                 /* Data RVA */
    739                                 fprintf(fp, "\t"DIRECTIVE_LONG"\t%s%s_data - %s%s\n",
    740                                         prefix,
    741                                         rsc->c_name,
    742                                         prefix,
    743                                         _PEResTab);
    744                                 /* Size */
    745                                 fprintf(fp, "\t"DIRECTIVE_LONG"\t%d\n",
    746                                         rsc->binres->size - rsc->binres->dataidx);
    747                                 /* CodePage */
    748                                 fprintf(fp, "\t"DIRECTIVE_LONG"\t%ld\n", codepage);
    749                                 /* Reserved */
    750                                 fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n");
    751 
    752                                 direntries++;
    753                         }
    754                         free(namelabel);
    755                 }
    756                 free(typelabel);
    757         }
     572    int i;
     573
     574    fprintf(fp, "\t"DIRECTIVE_ALIGN"\t4\n");
     575    fprintf(fp, "%s%s:\n", prefix, _PEResTab);
     576    fprintf(fp, "\t"DIRECTIVE_GLOBAL"\t%s%s\n", prefix, _PEResTab);
     577    /* Flags */
     578    fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n");
     579    /* Time/Date stamp */
     580    fprintf(fp, "\t"DIRECTIVE_LONG"\t"LONGFRMT"\n", (long)now);
     581    /* Version */
     582    fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n"); /* FIXME: must version be filled out? */
     583    /* # of id entries, # of name entries */
     584    fprintf(fp, "\t"DIRECTIVE_SHORT"\t%d, %d\n", n_name_entries, n_id_entries);
     585
     586    /* Write the type level of the tree */
     587    for(i = 0; i < rccount; i++)
     588    {
     589        res_count_t *rcp;
     590        char *label;
     591
     592        rcp = &rcarray[i];
     593
     594        /* TypeId */
     595        if(rcp->type.type == name_ord)
     596            fprintf(fp, "\t"DIRECTIVE_LONG"\t%d\n", rcp->type.name.i_name);
     597        else
     598        {
     599            char *name = prep_nid_for_label(&(rcp->type));
     600            fprintf(fp, "\t"DIRECTIVE_LONG"\t(%s_%s_typename - %s%s) "OR" "HEXBIT31"\n",
     601                prefix,
     602                name,
     603                prefix,
     604                _PEResTab);
     605        }
     606        /* Offset */
     607        label = prep_nid_for_label(&(rcp->type));
     608        fprintf(fp, "\t"DIRECTIVE_LONG"\t("LOCAL_PREFIX"L%s - %s%s) "OR" "HEXBIT31"\n",
     609            label,
     610            prefix,
     611            _PEResTab);
     612    }
     613
     614    /* Write the name level of the tree */
     615
     616    for(i = 0; i < rccount; i++)
     617    {
     618        res_count_t *rcp;
     619        char *typelabel;
     620        char *namelabel;
     621        int j;
     622
     623        rcp = &rcarray[i];
     624
     625        typelabel = xstrdup(prep_nid_for_label(&(rcp->type)));
     626        fprintf(fp, ""LOCAL_PREFIX"L%s:\n", typelabel);
     627
     628        fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n");     /* Flags */
     629        fprintf(fp, "\t"DIRECTIVE_LONG"\t"LONGFRMT"\n", (long)now); /* TimeDate */
     630        fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n"); /* FIXME: must version be filled out? */
     631        fprintf(fp, "\t"DIRECTIVE_SHORT"\t%d, %d\n", rcp->n_name_entries, rcp->n_id_entries);
     632        for(j = 0; j < rcp->count32; j++)
     633        {
     634            resource_t *rsc = rcp->rsc32array[j].rsc[0];
     635            /* NameId */
     636            if(rsc->name->type == name_ord)
     637                fprintf(fp, "\t"DIRECTIVE_LONG"\t%d\n", rsc->name->name.i_name);
     638            else
     639            {
     640                fprintf(fp, "\t"DIRECTIVE_LONG"\t(%s%s_name - %s%s) "OR" "HEXBIT31"\n",
     641                    prefix,
     642                    rsc->c_name,
     643                    prefix,
     644                    _PEResTab);
     645            }
     646            /* Maybe FIXME: Unescape the tree (ommit "HEXBIT31") and
     647            * put the offset to the resource data entry.
     648            * ?? Is unescaping worth while ??
     649            */
     650            /* Offset */
     651            namelabel = prep_nid_for_label(rsc->name);
     652            fprintf(fp, "\t"DIRECTIVE_LONG"\t("LOCAL_PREFIX"L%s_%s - %s%s) "OR" "HEXBIT31"\n",
     653                typelabel,
     654                namelabel,
     655                prefix,
     656                _PEResTab);
     657        }
     658        free(typelabel);
     659    }
     660
     661    /* Write the language level of the tree */
     662
     663    for(i = 0; i < rccount; i++)
     664    {
     665        res_count_t *rcp;
     666        char *namelabel;
     667        char *typelabel;
     668        int j;
     669
     670        rcp = &rcarray[i];
     671        typelabel = xstrdup(prep_nid_for_label(&(rcp->type)));
     672
     673        for(j = 0; j < rcp->count32; j++)
     674        {
     675            res32_count_t *r32cp = &(rcp->rsc32array[j]);
     676            int k;
     677
     678            namelabel = xstrdup(prep_nid_for_label(r32cp->rsc[0]->name));
     679            fprintf(fp, ""LOCAL_PREFIX"L%s_%s:\n", typelabel, namelabel);
     680
     681            fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n");     /* Flags */
     682            fprintf(fp, "\t"DIRECTIVE_LONG"\t"LONGFRMT"\n", (long)now); /* TimeDate */
     683            fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n"); /* FIXME: must version be filled out? */
     684            fprintf(fp, "\t"DIRECTIVE_SHORT"\t0, %d\n", r32cp->count);
     685
     686            for(k = 0; k < r32cp->count; k++)
     687            {
     688                resource_t *rsc = r32cp->rsc[k];
     689                assert(rsc->lan != NULL);
     690                /* LanguageId */
     691                fprintf(fp, "\t"DIRECTIVE_LONG"\t"LONGFRMT"\n", rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0);
     692                /* Offset */
     693                fprintf(fp, "\t"DIRECTIVE_LONG"\t"LOCAL_PREFIX"L%s_%s_%d - %s%s\n",
     694                    typelabel,
     695                    namelabel,
     696                    rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0,
     697                    prefix,
     698                    _PEResTab);
     699            }
     700            free(namelabel);
     701        }
     702        free(typelabel);
     703    }
     704
     705    /* Write the resource table itself */
     706    fprintf(fp, "%s_ResourceDirectory:\n", prefix);
     707    fprintf(fp, "\t"DIRECTIVE_GLOBAL"\t%s_ResourceDirectory\n", prefix);
     708    direntries = 0;
     709
     710    for(i = 0; i < rccount; i++)
     711    {
     712        res_count_t *rcp;
     713        char *namelabel;
     714        char *typelabel;
     715        int j;
     716
     717        rcp = &rcarray[i];
     718        typelabel = xstrdup(prep_nid_for_label(&(rcp->type)));
     719
     720        for(j = 0; j < rcp->count32; j++)
     721        {
     722            res32_count_t *r32cp = &(rcp->rsc32array[j]);
     723            int k;
     724
     725            namelabel = xstrdup(prep_nid_for_label(r32cp->rsc[0]->name));
     726
     727            for(k = 0; k < r32cp->count; k++)
     728            {
     729                resource_t *rsc = r32cp->rsc[k];
     730
     731                assert(rsc->lan != NULL);
     732
     733                fprintf(fp, ""LOCAL_PREFIX"L%s_%s_%d:\n",
     734                    typelabel,
     735                    namelabel,
     736                    rsc->lan ? MAKELANGID(rsc->lan->id, rsc->lan->sub) : 0);
     737
     738                /* Data RVA */
     739                fprintf(fp, "\t"DIRECTIVE_LONG"\t%s%s_data - %s%s\n",
     740                    prefix,
     741                    rsc->c_name,
     742                    prefix,
     743                    _PEResTab);
     744                /* Size */
     745                fprintf(fp, "\t"DIRECTIVE_LONG"\t%d\n",
     746                    rsc->binres->size - rsc->binres->dataidx);
     747                /* CodePage */
     748                fprintf(fp, "\t"DIRECTIVE_LONG"\t%ld\n", codepage);
     749                /* Reserved */
     750                fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n");
     751
     752                direntries++;
     753            }
     754            free(namelabel);
     755        }
     756        free(typelabel);
     757    }
    758758}
    759759
    760760/*
    761761 *****************************************************************************
    762  * Function     : write_ne_segment
    763  * Syntax       : void write_ne_segment(FILE *fp)
    764  * Input        :
    765  * Output       :
    766  * Description  :
    767  * Remarks      :
     762 * Function : write_ne_segment
     763 * Syntax   : void write_ne_segment(FILE *fp)
     764 * Input    :
     765 * Output   :
     766 * Description  :
     767 * Remarks  :
    768768 *****************************************************************************
    769769*/
    770770static void write_ne_segment(FILE *fp)
    771771{
    772         int i, j;
    773 
    774         fprintf(fp, "\t"DIRECTIVE_ALIGN"\t4\n");
    775         fprintf(fp, "%s%s:\n", prefix, _NEResTab);
    776         fprintf(fp, "\t"DIRECTIVE_GLOBAL"\t%s%s\n", prefix, _NEResTab);
    777 
    778         /* AlignmentShift */
    779         fprintf(fp, "\t"DIRECTIVE_SHORT"\t%d\n", alignment_pwr);
    780 
    781         /* TypeInfo */
    782         for(i = 0; i < rccount; i++)
    783         {
    784                 res_count_t *rcp = &rcarray[i];
    785 
    786                 /* TypeId */
    787                 if(rcp->type.type == name_ord)
    788                         fprintf(fp, "\t"DIRECTIVE_SHORT"\t"SHORTFRMT"\n", rcp->type.name.i_name | 0x8000);
    789                 else
    790                         fprintf(fp, "\t"DIRECTIVE_SHORT"\t%s_%s_typename - %s%s\n",
    791                                 prefix,
    792                                 rcp->type.name.s_name->str.cstr,
    793                                 prefix,
    794                                 _NEResTab);
    795                 /* ResourceCount */
    796                 fprintf(fp, "\t"DIRECTIVE_SHORT"\t%d\n", rcp->count);
    797                 /* Reserved */
    798                 fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n");
    799                 /* NameInfo */
    800                 for(j = 0; j < rcp->count; j++)
    801                 {
     772    int i, j;
     773
     774    fprintf(fp, "\t"DIRECTIVE_ALIGN"\t4\n");
     775    fprintf(fp, "%s%s:\n", prefix, _NEResTab);
     776    fprintf(fp, "\t"DIRECTIVE_GLOBAL"\t%s%s\n", prefix, _NEResTab);
     777
     778    /* AlignmentShift */
     779    fprintf(fp, "\t"DIRECTIVE_SHORT"\t%d\n", alignment_pwr);
     780
     781    /* TypeInfo */
     782    for(i = 0; i < rccount; i++)
     783    {
     784        res_count_t *rcp = &rcarray[i];
     785
     786        /* TypeId */
     787        if(rcp->type.type == name_ord)
     788            fprintf(fp, "\t"DIRECTIVE_SHORT"\t"SHORTFRMT"\n", rcp->type.name.i_name | 0x8000);
     789        else
     790            fprintf(fp, "\t"DIRECTIVE_SHORT"\t%s_%s_typename - %s%s\n",
     791                prefix,
     792                rcp->type.name.s_name->str.cstr,
     793                prefix,
     794                _NEResTab);
     795        /* ResourceCount */
     796        fprintf(fp, "\t"DIRECTIVE_SHORT"\t%d\n", rcp->count);
     797        /* Reserved */
     798        fprintf(fp, "\t"DIRECTIVE_LONG"\t0\n");
     799        /* NameInfo */
     800        for(j = 0; j < rcp->count; j++)
     801        {
    802802/*
    803803 * VERY IMPORTANT:
     
    808808 * All other things are as the MS doc describes (alignment etc.)
    809809 */
    810                         /* Offset */
    811                         fprintf(fp, "\t"DIRECTIVE_SHORT"\t(%s%s_data - %s%s) >> %d\n",
    812                                 prefix,
    813                                 rcp->rscarray[j]->c_name,
    814                                 prefix,
    815                                 _NEResTab,
    816                                 alignment_pwr);
    817                         /* Length */
    818                         fprintf(fp, "\t"DIRECTIVE_SHORT"\t%d\n",
    819                                 (rcp->rscarray[j]->binres->size - rcp->rscarray[j]->binres->dataidx + alignment - 1) >> alignment_pwr);
    820                         /* Flags */
    821                         fprintf(fp, "\t"DIRECTIVE_SHORT"\t"SHORTFRMT"\n", (WORD)rcp->rscarray[j]->memopt);
    822                         /* Id */
    823                         if(rcp->rscarray[j]->name->type == name_ord)
    824                                 fprintf(fp, "\t"DIRECTIVE_SHORT"\t"SHORTFRMT"\n", rcp->rscarray[j]->name->name.i_name | 0x8000);
    825                         else
    826                                 fprintf(fp, "\t"DIRECTIVE_SHORT"\t%s%s_name - %s%s\n",
    827                                 prefix,
    828                                 rcp->rscarray[j]->c_name,
    829                                 prefix,
    830                                 _NEResTab);
    831                         /* Handle and Usage */
    832                         fprintf(fp, "\t"DIRECTIVE_SHORT"\t0, 0\n");
    833                 }
    834         }
    835         /* EndTypes */
    836         fprintf(fp, "\t"DIRECTIVE_SHORT"\t0\n");
     810            /* Offset */
     811            fprintf(fp, "\t"DIRECTIVE_SHORT"\t(%s%s_data - %s%s) >> %d\n",
     812                prefix,
     813                rcp->rscarray[j]->c_name,
     814                prefix,
     815                _NEResTab,
     816                alignment_pwr);
     817            /* Length */
     818            fprintf(fp, "\t"DIRECTIVE_SHORT"\t%d\n",
     819                (rcp->rscarray[j]->binres->size - rcp->rscarray[j]->binres->dataidx + alignment - 1) >> alignment_pwr);
     820            /* Flags */
     821            fprintf(fp, "\t"DIRECTIVE_SHORT"\t"SHORTFRMT"\n", (WORD)rcp->rscarray[j]->memopt);
     822            /* Id */
     823            if(rcp->rscarray[j]->name->type == name_ord)
     824                fprintf(fp, "\t"DIRECTIVE_SHORT"\t"SHORTFRMT"\n", rcp->rscarray[j]->name->name.i_name | 0x8000);
     825            else
     826                fprintf(fp, "\t"DIRECTIVE_SHORT"\t%s%s_name - %s%s\n",
     827                prefix,
     828                rcp->rscarray[j]->c_name,
     829                prefix,
     830                _NEResTab);
     831            /* Handle and Usage */
     832            fprintf(fp, "\t"DIRECTIVE_SHORT"\t0, 0\n");
     833        }
     834    }
     835    /* EndTypes */
     836    fprintf(fp, "\t"DIRECTIVE_SHORT"\t0\n");
    837837}
    838838
    839839/*
    840840 *****************************************************************************
    841  * Function     : write_rsc_names
    842  * Syntax       : void write_rsc_names(FILE *fp)
    843  * Input        :
    844  * Output       :
    845  * Description  :
    846  * Remarks      :
     841 * Function : write_rsc_names
     842 * Syntax   : void write_rsc_names(FILE *fp)
     843 * Input    :
     844 * Output   :
     845 * Description  :
     846 * Remarks  :
    847847 *****************************************************************************
    848848*/
    849849static void write_rsc_names(FILE *fp)
    850850{
    851         int i, j;
    852        
    853         if(win32)
    854         {
    855                 /* Write the names */
    856 
    857                 for(i = 0; i < rccount; i++)
    858                 {
    859                         res_count_t *rcp;
    860 
    861                         rcp = &rcarray[i];
    862 
    863                         if(rcp->type.type == name_str)
    864                         {
    865                                 char *name = prep_nid_for_label(&(rcp->type));
    866                                 fprintf(fp, "%s_%s_typename:\n",
    867                                         prefix,
    868                                         name);
    869                                 write_name_str(fp, &(rcp->type));
    870                         }
    871 
    872                         for(j = 0; j < rcp->count32; j++)
    873                         {
    874                                 resource_t *rsc = rcp->rsc32array[j].rsc[0];
    875 
    876                                 if(rsc->name->type == name_str)
    877                                 {
    878                                         fprintf(fp, "%s%s_name:\n",
    879                                                 prefix,
    880                                                 rsc->c_name);
    881                                         write_name_str(fp, rsc->name);
    882                                 }
    883                         }
    884                 }
    885         }
    886         else
    887         {
    888                 /* ResourceNames */
    889                 for(i = 0; i < rccount; i++)
    890                 {
    891                         res_count_t *rcp = &rcarray[i];
    892 
    893                         if(rcp->type.type == name_str)
    894                         {
    895                                 fprintf(fp, "%s_%s_typename:\n",
    896                                         prefix,
    897                                         rcp->type.name.s_name->str.cstr);
    898                                 write_name_str(fp, &(rcp->type));
    899                         }
    900                         for(j = 0; j < rcp->count; j++)
    901                         {
    902                                 if(rcp->rscarray[j]->name->type == name_str)
    903                                 {
    904                                         fprintf(fp, "%s%s_name:\n",
    905                                                 prefix,
    906                                                 rcp->rscarray[j]->c_name);
    907                                         write_name_str(fp, rcp->rscarray[j]->name);
    908                                 }
    909                         }
    910                 }
    911                 /* EndNames */
    912                
    913                 /* This is to end the NE resource table */
    914                 if(create_dir)
    915                         fprintf(fp, "\t"DIRECTIVE_BYTE"\t0\n");
    916         }
    917 
    918         fprintf(fp, "\n");
     851    int i, j;
     852
     853    if(win32)
     854    {
     855        /* Write the names */
     856
     857        for(i = 0; i < rccount; i++)
     858        {
     859            res_count_t *rcp;
     860
     861            rcp = &rcarray[i];
     862
     863            if(rcp->type.type == name_str)
     864            {
     865                char *name = prep_nid_for_label(&(rcp->type));
     866                fprintf(fp, "%s_%s_typename:\n",
     867                    prefix,
     868                    name);
     869                write_name_str(fp, &(rcp->type));
     870            }
     871
     872            for(j = 0; j < rcp->count32; j++)
     873            {
     874                resource_t *rsc = rcp->rsc32array[j].rsc[0];
     875
     876                if(rsc->name->type == name_str)
     877                {
     878                    fprintf(fp, "%s%s_name:\n",
     879                        prefix,
     880                        rsc->c_name);
     881                    write_name_str(fp, rsc->name);
     882                }
     883            }
     884        }
     885    }
     886    else
     887    {
     888        /* ResourceNames */
     889        for(i = 0; i < rccount; i++)
     890        {
     891            res_count_t *rcp = &rcarray[i];
     892
     893            if(rcp->type.type == name_str)
     894            {
     895                fprintf(fp, "%s_%s_typename:\n",
     896                    prefix,
     897                    rcp->type.name.s_name->str.cstr);
     898                write_name_str(fp, &(rcp->type));
     899            }
     900            for(j = 0; j < rcp->count; j++)
     901            {
     902                if(rcp->rscarray[j]->name->type == name_str)
     903                {
     904                    fprintf(fp, "%s%s_name:\n",
     905                        prefix,
     906                        rcp->rscarray[j]->c_name);
     907                    write_name_str(fp, rcp->rscarray[j]->name);
     908                }
     909            }
     910        }
     911        /* EndNames */
     912
     913        /* This is to end the NE resource table */
     914        if(create_dir)
     915            fprintf(fp, "\t"DIRECTIVE_BYTE"\t0\n");
     916    }
     917
     918    fprintf(fp, "\n");
    919919}
    920920
    921921/*
    922922 *****************************************************************************
    923  * Function     : write_s_file
    924  * Syntax       : void write_s_file(char *outname, resource_t *top)
    925  * Input        :
    926  *      outname - Filename to write to
    927  *      top     - The resource-tree to convert
    928  * Output       :
    929  * Description  :
    930  * Remarks      :
     923 * Function : write_s_file
     924 * Syntax   : void write_s_file(char *outname, resource_t *top)
     925 * Input    :
     926 *  outname - Filename to write to
     927 *  top - The resource-tree to convert
     928 * Output   :
     929 * Description  :
     930 * Remarks  :
    931931 *****************************************************************************
    932932*/
    933933void write_s_file(char *outname, resource_t *top)
    934934{
    935         FILE *fo;
    936         resource_t *rsc;
    937 
    938         fo = fopen(outname, "wt");
    939         if(!fo)
    940         {
    941                 error("Could not open %s\n", outname);
    942                 return;
    943         }
    944 
    945         {
    946                 char *s, *p;
    947                 s = ctime(&now);
    948                 p = strchr(s, '\n');
    949                 if(p) *p = '\0';
    950                 fprintf(fo, s_file_head_str, input_name ? input_name : "stdin",
    951                         cmdline, s);
    952         }
    953 
    954         /* Get an idea how many we have and restructure the tables */
    955         count_resources(top);
    956 
    957         /* First write the segment tables */
    958         if(create_dir)
    959         {
    960                 if(win32)
    961                         write_pe_segment(fo);
    962                 else
    963                         write_ne_segment(fo);
    964         }
    965 
    966         /* Dump the names */
    967         write_rsc_names(fo);
    968 
    969         if(create_dir)
    970                 fprintf(fo, LOCAL_PREFIX"LResTabEnd:\n");
    971        
    972         if(!indirect_only)
    973         {
    974                 /* Write the resource data */
     935    FILE *fo;
     936    resource_t *rsc;
     937
     938    #ifdef __WIN32OS2__
     939    fo = fopen(outname, "w");
     940    #else
     941    fo = fopen(outname, "wt");
     942    #endif
     943    if(!fo)
     944    {
     945        error("Could not open %s\n", outname);
     946        return;
     947    }
     948
     949    {
     950        char *s, *p;
     951        s = ctime(&now);
     952        p = strchr(s, '\n');
     953        if(p) *p = '\0';
     954        fprintf(fo, s_file_head_str, input_name ? input_name : "stdin",
     955            cmdline, s);
     956    }
     957
     958    /* Get an idea how many we have and restructure the tables */
     959    count_resources(top);
     960
     961    /* First write the segment tables */
     962    if(create_dir)
     963    {
     964        if(win32)
     965            write_pe_segment(fo);
     966        else
     967            write_ne_segment(fo);
     968    }
     969
     970    /* Dump the names */
     971    write_rsc_names(fo);
     972
     973    if(create_dir)
     974        fprintf(fo, LOCAL_PREFIX"LResTabEnd:\n");
     975
     976    if(!indirect_only)
     977    {
     978        /* Write the resource data */
    975979#ifdef MASM
    976                 fprintf(fo, "\n; Resource binary data */\n\n");
     980            fprintf(fo, "\n; Resource binary data */\n\n");
    977981#else
    978                 fprintf(fo, "\n/* Resource binary data */\n\n");
     982            fprintf(fo, "\n/* Resource binary data */\n\n");
    979983#endif
    980                 for(rsc = top; rsc; rsc = rsc->next)
    981                 {
    982                         if(!rsc->binres)
    983                                 continue;
    984 
    985                         fprintf(fo, "\t"DIRECTIVE_ALIGN"\t%d\n", win32 ? 4 : alignment);
    986                         fprintf(fo, "%s%s_data:\n", prefix, rsc->c_name);
    987                         if(global)
    988                                 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s%s_data\n", prefix, rsc->c_name);
    989 
    990                         write_s_res(fo, rsc->binres);
    991 
    992                         fprintf(fo, "\n");
    993                 }
    994 
    995                 if(create_dir)
    996                 {
    997                         /* Add a resource descriptor for built-in and elf-dlls */
    998                         fprintf(fo, "\t"DIRECTIVE_ALIGN"\t4\n");
    999                         fprintf(fo, "%s_ResourceDescriptor:\n", prefix);
    1000                         fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_ResourceDescriptor\n", prefix);
    1001                         fprintf(fo, "%s_ResourceTable:\n", prefix);
    1002                         if(global)
    1003                                 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_ResourceTable\n", prefix);
    1004                         fprintf(fo, "\t"DIRECTIVE_LONG"\t%s%s\n", prefix, win32 ? _PEResTab : _NEResTab);
    1005                         fprintf(fo, "%s_NumberOfResources:\n", prefix);
    1006                         if(global)
    1007                                 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_NumberOfResources\n", prefix);
    1008                         fprintf(fo, "\t"DIRECTIVE_LONG"\t%d\n", direntries);
    1009                         fprintf(fo, "%s_ResourceSectionSize:\n", prefix);
    1010                         if(global)
    1011                                 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_ResourceSectionSize\n", prefix);
    1012                         fprintf(fo, "\t"DIRECTIVE_LONG"\t"LOCAL_PREFIX"LResTabEnd - %s%s\n", prefix, win32 ? _PEResTab : _NEResTab);
    1013                         if(win32)
    1014                         {
    1015                                 fprintf(fo, "%s_ResourcesEntries:\n", prefix);
    1016                                 if(global)
    1017                                         fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_ResourcesEntries\n", prefix);
    1018                                 fprintf(fo, "\t"DIRECTIVE_LONG"\t%s_ResourceDirectory\n", prefix);
    1019                         }
    1020                 }
    1021         }
    1022 
    1023         if(indirect)
    1024         {
    1025                 /* Write the indirection structures */
    1026                 fprintf(fo, "\n/* Resource indirection structures */\n\n");
    1027                 fprintf(fo, "\t"DIRECTIVE_ALIGN"\t4\n");
    1028                 for(rsc = top; rsc; rsc = rsc->next)
    1029                 {
    1030                         int type;
    1031                         char *type_name = NULL;
    1032 
    1033                         if(!rsc->binres)
    1034                                 continue;
    1035 
    1036                         switch(rsc->type)
    1037                         {
    1038                         case res_menex:
    1039                                 type = WRC_RT_MENU;
    1040                                 break;
    1041                         case res_dlgex:
    1042                                 type = WRC_RT_DIALOG;
    1043                                 break;
    1044                         case res_usr:
    1045                                 assert(rsc->res.usr->type != NULL);
    1046                                 type_name = prep_nid_for_label(rsc->res.usr->type);
    1047                                 type = 0;
    1048                                 break;
    1049                         default:
    1050                                 type = rsc->type;
    1051                         }
    1052 
    1053                         /*
    1054                         * This follows a structure like:
    1055                         * struct wrc_resource {
    1056                          *      INT32   id;
    1057                          *      RSCNAME *resname;
    1058                          *      INT32   restype;
    1059                          *      RSCNAME *typename;
    1060                          *      void    *data;
    1061                          *      UINT32  datasize;
    1062                         * };
    1063                         * The 'RSCNAME' is a pascal-style string where the
    1064                         * first byte/word denotes the size and the rest the string
    1065                         * itself.
    1066                         */
    1067                         fprintf(fo, "%s%s:\n", prefix, rsc->c_name);
    1068                         if(global)
    1069                                 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s%s\n", prefix, rsc->c_name);
    1070                         fprintf(fo, "\t"DIRECTIVE_LONG"\t%d, %s%s%s, %d, %s%s%s%s, %s%s_data, %d\n",
    1071                                 rsc->name->type == name_ord ? rsc->name->name.i_name : 0,
    1072                                 rsc->name->type == name_ord ? "0" : prefix,
    1073                                 rsc->name->type == name_ord ? "" : rsc->c_name,
    1074                                 rsc->name->type == name_ord ? "" : "_name",
    1075                                 type,
    1076                                 type ? "0" : prefix,
    1077                                 type ? "" : "_",
    1078                                 type ? "" : type_name,
    1079                                 type ? "" : "_typename",
    1080                                 prefix,
    1081                                 rsc->c_name,
    1082                                 rsc->binres->size - rsc->binres->dataidx);
    1083                         fprintf(fo, "\n");
    1084                 }
    1085                 fprintf(fo, "\n");
    1086 
    1087                 /* Write the indirection table */
    1088                 fprintf(fo, "/* Resource indirection table */\n\n");
    1089                 fprintf(fo, "\t"DIRECTIVE_ALIGN"\t4\n");
    1090                 fprintf(fo, "%s%s:\n", prefix, _ResTable);
    1091                 fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s%s\n", prefix, _ResTable);
    1092                 for(rsc = top; rsc; rsc = rsc->next)
    1093                 {
    1094                         fprintf(fo, "\t"DIRECTIVE_LONG"\t%s%s\n", prefix, rsc->c_name);
    1095                 }
    1096                 fprintf(fo, "\t"DIRECTIVE_LONG"\t0\n");
    1097                 fprintf(fo, "\n");
    1098         }
    1099 
    1100         if(auto_register)
    1101                 fprintf(fo, s_file_autoreg_str, prefix, _ResTable);
    1102 
    1103         fprintf(fo, s_file_tail_str);
    1104         fclose(fo);
     984        for(rsc = top; rsc; rsc = rsc->next)
     985        {
     986            if(!rsc->binres)
     987                continue;
     988
     989            fprintf(fo, "\t"DIRECTIVE_ALIGN"\t%d\n", win32 ? 4 : alignment);
     990            fprintf(fo, "%s%s_data:\n", prefix, rsc->c_name);
     991            if(global)
     992                fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s%s_data\n", prefix, rsc->c_name);
     993
     994            write_s_res(fo, rsc->binres);
     995
     996            fprintf(fo, "\n");
     997        }
     998
     999        if(create_dir)
     1000        {
     1001            /* Add a resource descriptor for built-in and elf-dlls */
     1002            fprintf(fo, "\t"DIRECTIVE_ALIGN"\t4\n");
     1003            fprintf(fo, "%s_ResourceDescriptor:\n", prefix);
     1004            fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_ResourceDescriptor\n", prefix);
     1005            fprintf(fo, "%s_ResourceTable:\n", prefix);
     1006            if(global)
     1007                fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_ResourceTable\n", prefix);
     1008            fprintf(fo, "\t"DIRECTIVE_LONG"\t%s%s\n", prefix, win32 ? _PEResTab : _NEResTab);
     1009            fprintf(fo, "%s_NumberOfResources:\n", prefix);
     1010            if(global)
     1011                fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_NumberOfResources\n", prefix);
     1012            fprintf(fo, "\t"DIRECTIVE_LONG"\t%d\n", direntries);
     1013            fprintf(fo, "%s_ResourceSectionSize:\n", prefix);
     1014            if(global)
     1015                fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_ResourceSectionSize\n", prefix);
     1016            fprintf(fo, "\t"DIRECTIVE_LONG"\t"LOCAL_PREFIX"LResTabEnd - %s%s\n", prefix, win32 ? _PEResTab : _NEResTab);
     1017            if(win32)
     1018            {
     1019                fprintf(fo, "%s_ResourcesEntries:\n", prefix);
     1020                if(global)
     1021                    fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s_ResourcesEntries\n", prefix);
     1022                fprintf(fo, "\t"DIRECTIVE_LONG"\t%s_ResourceDirectory\n", prefix);
     1023            }
     1024        }
     1025    }
     1026
     1027    if(indirect)
     1028    {
     1029        /* Write the indirection structures */
     1030            fprintf(fo, "\n/* Resource indirection structures */\n\n");
     1031        fprintf(fo, "\t"DIRECTIVE_ALIGN"\t4\n");
     1032        for(rsc = top; rsc; rsc = rsc->next)
     1033        {
     1034            int type;
     1035            char *type_name = NULL;
     1036
     1037            if(!rsc->binres)
     1038                continue;
     1039
     1040            switch(rsc->type)
     1041            {
     1042            case res_menex:
     1043                type = WRC_RT_MENU;
     1044                break;
     1045            case res_dlgex:
     1046                type = WRC_RT_DIALOG;
     1047                break;
     1048            case res_usr:
     1049                assert(rsc->res.usr->type != NULL);
     1050                type_name = prep_nid_for_label(rsc->res.usr->type);
     1051                type = 0;
     1052                break;
     1053            default:
     1054                type = rsc->type;
     1055            }
     1056
     1057            /*
     1058            * This follows a structure like:
     1059            * struct wrc_resource {
     1060             *  INT32   id;
     1061             *  RSCNAME *resname;
     1062             *  INT32   restype;
     1063             *  RSCNAME *typename;
     1064             *  void    *data;
     1065             *  UINT32  datasize;
     1066            * };
     1067            * The 'RSCNAME' is a pascal-style string where the
     1068            * first byte/word denotes the size and the rest the string
     1069            * itself.
     1070            */
     1071            fprintf(fo, "%s%s:\n", prefix, rsc->c_name);
     1072            if(global)
     1073                fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s%s\n", prefix, rsc->c_name);
     1074            fprintf(fo, "\t"DIRECTIVE_LONG"\t%d, %s%s%s, %d, %s%s%s%s, %s%s_data, %d\n",
     1075                rsc->name->type == name_ord ? rsc->name->name.i_name : 0,
     1076                rsc->name->type == name_ord ? "0" : prefix,
     1077                rsc->name->type == name_ord ? "" : rsc->c_name,
     1078                rsc->name->type == name_ord ? "" : "_name",
     1079                type,
     1080                type ? "0" : prefix,
     1081                type ? "" : "_",
     1082                type ? "" : type_name,
     1083                type ? "" : "_typename",
     1084                prefix,
     1085                rsc->c_name,
     1086                rsc->binres->size - rsc->binres->dataidx);
     1087            fprintf(fo, "\n");
     1088        }
     1089        fprintf(fo, "\n");
     1090
     1091        /* Write the indirection table */
     1092        fprintf(fo, "/* Resource indirection table */\n\n");
     1093        fprintf(fo, "\t"DIRECTIVE_ALIGN"\t4\n");
     1094        fprintf(fo, "%s%s:\n", prefix, _ResTable);
     1095        fprintf(fo, "\t"DIRECTIVE_GLOBAL"\t%s%s\n", prefix, _ResTable);
     1096        for(rsc = top; rsc; rsc = rsc->next)
     1097        {
     1098            fprintf(fo, "\t"DIRECTIVE_LONG"\t%s%s\n", prefix, rsc->c_name);
     1099        }
     1100        fprintf(fo, "\t"DIRECTIVE_LONG"\t0\n");
     1101        fprintf(fo, "\n");
     1102    }
     1103
     1104    if(auto_register)
     1105        fprintf(fo, s_file_autoreg_str, prefix, _ResTable);
     1106
     1107    fprintf(fo, s_file_tail_str);
     1108    fclose(fo);
    11051109}
    11061110
    11071111/*
    11081112 *****************************************************************************
    1109  * Function     : write_h_file
    1110  * Syntax       : void write_h_file(char *outname, resource_t *top)
    1111  * Input        :
    1112  *      outname - Filename to write to
    1113  *      top     - The resource-tree to convert
    1114  * Output       :
    1115  * Description  :
    1116  * Remarks      :
     1113 * Function : write_h_file
     1114 * Syntax   : void write_h_file(char *outname, resource_t *top)
     1115 * Input    :
     1116 *  outname - Filename to write to
     1117 *  top - The resource-tree to convert
     1118 * Output   :
     1119 * Description  :
     1120 * Remarks  :
    11171121 *****************************************************************************
    11181122*/
    11191123void write_h_file(char *outname, resource_t *top)
    11201124{
    1121         FILE *fo;
    1122         resource_t *rsc;
    1123         char *h_prefix;
     1125    FILE *fo;
     1126    resource_t *rsc;
     1127    char *h_prefix;
    11241128
    11251129#ifdef NEED_UNDERSCORE_PREFIX
    1126         h_prefix = prefix + 1;
     1130    h_prefix = prefix + 1;
    11271131#else
    1128         h_prefix = prefix;
     1132    h_prefix = prefix;
    11291133#endif
    11301134
    1131         fo = fopen(outname, "wt");
    1132         if(!fo)
    1133         {
    1134                 error("Could not open %s\n", outname);
    1135         }
    1136 
    1137         fprintf(fo, h_file_head_str, input_name ? input_name : "stdin",
     1135    #ifdef __WIN32OS2__
     1136    fo = fopen(outname, "w");
     1137    #else
     1138    fo = fopen(outname, "wt");
     1139    #endif
     1140    if(!fo)
     1141    {
     1142        error("Could not open %s\n", outname);
     1143    }
     1144
     1145    fprintf(fo, h_file_head_str, input_name ? input_name : "stdin",
    11381146                cmdline, ctime(&now), (long)now, (long)now);
    11391147
    1140         /* First write the segment tables reference */
    1141         if(create_dir)
    1142         {
    1143                 fprintf(fo, "extern %schar %s%s[];\n\n",
    1144                         constant ? "const " : "",
    1145                         h_prefix,
    1146                         win32 ? _PEResTab : _NEResTab);
    1147         }
    1148 
    1149         /* Write the resource data */
    1150         for(rsc = top; global && rsc; rsc = rsc->next)
    1151         {
    1152                 if(!rsc->binres)
    1153                         continue;
    1154 
    1155                 fprintf(fo, "extern %schar %s%s_data[];\n",
    1156                         constant ? "const " : "",
    1157                         h_prefix,
    1158                         rsc->c_name);
    1159         }
    1160 
    1161         if(indirect)
    1162         {
    1163                 if(global)
    1164                         fprintf(fo, "\n");
    1165 
    1166                 /* Write the indirection structures */
    1167                 for(rsc = top; global && rsc; rsc = rsc->next)
    1168                 {
    1169                         fprintf(fo, "extern %swrc_resource%d_t %s%s;\n",
    1170                                 constant ? "const " : "",
    1171                                 win32 ? 32 : 16,
    1172                                 h_prefix,
    1173                                 rsc->c_name);
    1174                 }
    1175 
    1176                 if(global)
    1177                         fprintf(fo, "\n");
    1178 
    1179                 /* Write the indirection table */
    1180                 fprintf(fo, "extern %swrc_resource%d_t %s%s[];\n\n",
    1181                         constant ? "const " : "",
    1182                         win32 ? 32 : 16,
    1183                         h_prefix,
    1184                         _ResTable);
    1185         }
    1186 
    1187         fprintf(fo, h_file_tail_str);
    1188         fclose(fo);
    1189 }
    1190 
     1148    /* First write the segment tables reference */
     1149    if(create_dir)
     1150    {
     1151        fprintf(fo, "extern %schar %s%s[];\n\n",
     1152            constant ? "const " : "",
     1153            h_prefix,
     1154            win32 ? _PEResTab : _NEResTab);
     1155    }
     1156
     1157    /* Write the resource data */
     1158    for(rsc = top; global && rsc; rsc = rsc->next)
     1159    {
     1160        if(!rsc->binres)
     1161            continue;
     1162
     1163        fprintf(fo, "extern %schar %s%s_data[];\n",
     1164            constant ? "const " : "",
     1165            h_prefix,
     1166            rsc->c_name);
     1167    }
     1168
     1169    if(indirect)
     1170    {
     1171        if(global)
     1172            fprintf(fo, "\n");
     1173
     1174        /* Write the indirection structures */
     1175        for(rsc = top; global && rsc; rsc = rsc->next)
     1176        {
     1177            fprintf(fo, "extern %swrc_resource%d_t %s%s;\n",
     1178                constant ? "const " : "",
     1179                win32 ? 32 : 16,
     1180                h_prefix,
     1181                rsc->c_name);
     1182        }
     1183
     1184        if(global)
     1185            fprintf(fo, "\n");
     1186
     1187        /* Write the indirection table */
     1188        fprintf(fo, "extern %swrc_resource%d_t %s%s[];\n\n",
     1189            constant ? "const " : "",
     1190            win32 ? 32 : 16,
     1191            h_prefix,
     1192            _ResTable);
     1193    }
     1194
     1195    fprintf(fo, h_file_tail_str);
     1196    fclose(fo);
     1197}
     1198
Note: See TracChangeset for help on using the changeset viewer.