1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714
  
     | 
    
      /*
 * build.h
 * 
 * This file is a part of NSIS.
 * 
 * Copyright (C) 1999-2021 Nullsoft and Contributors
 * 
 * Licensed under the zlib/libpng license (the "License");
 * you may not use this file except in compliance with the License.
 * 
 * Licence details can be found in the file COPYING.
 * 
 * This software is provided 'as-is', without any express or implied
 * warranty.
 *
 * Unicode support by Jim Park -- 08/10/2007
 */
#ifndef _BUILD_H_
#define _BUILD_H_
#include "strlist.h"
#include "lineparse.h"
#include "lang.h"
#include "ResourceEditor.h"
#include "ResourceVersionInfo.h"
#include "uservars.h"
#include "ShConstants.h"
#include "mmap.h"
#include "manifest.h"
#include "icon.h"
#include <memory.h>
#include "utf.h"
#include "exehead/fileform.h"
#include "exehead/config.h"
#include "tstring.h"
#include <set>
#include <map>
#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
// Added by Sunil Kamath 11 June 2003
#  include <time.h>
#  include <sys/stat.h>
#endif
#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
// Changed by Amir Szekely 31st July 2002
#include "compressor.h"
#include "czlib.h"
#include "cbzip2.h"
#include "clzma.h"
#endif //~ NSIS_CONFIG_COMPRESSION_SUPPORT
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
#  include "Plugins.h"
#endif //~ NSIS_CONFIG_PLUGIN_SUPPORT
// 1000..4999 Errors
// 5000..5999 Important generic warnings
// 6000..6999 Script warnings
// 7000..7499 Recovered from bad input etc. warnings
// 7500..7999 Discouraged usage warnings (allocated high to low to reserve as much space as possible for more bad input codes)
// 8000..8999 Generic warnings
// 9000..9999 Breaking our and/or MS guidelines warnings
typedef enum {
  //DE_OOM = 1000?, // Generic out of memory
  //DE_MMAP = 1001?,
  //DE_STUB_SECTION = 1100?,
  //DE_PP_VERBOSE_BAD_LEVEL = 4000?,
  //DW_STALE_TEMP = 5020?, TODO: There is currently no way to disable this
  DW_PACKHDR_RETNONZERO = 5021,
  DW_BADFORMAT_EXTERNAL_FILE = 5040,
  DW_UNSUPP_STORE_FILE_ATT = 5050,
  //DW_CMDLINE_UNSUPP = 5200?,
  //DW_CMDLINE_UNSUPP_WIN = 5201?,
  DW_CMDLINE_UNSUPP_NIX = 5202,
  DW_CMDLINE_BAD_INPUTENC = 5210, // reserved ..5229
  DW_VAR_IGNORED_UNKNOWN = 6000, // reserved ..6009
  DW_VAR_NOREF = 6001,
  DW_UNUSED_FUNCTION = 6010, // reserved ..6019
  DW_UNUSED_GLOBALLABEL = 6011,
  DW_UNUSED_LABEL = 6012,
  DW_UNCODE_WITHOUT_UNEXE = 6020,
  DW_INNERSTRING_MULTISETWASTE = 6029,
  DW_STRING_MULTISETWASTE = DW_INNERSTRING_MULTISETWASTE,
  DW_LANGSTRING_MULTISETWASTE = 6030, // reserved ..6049
  DW_LANGSTRING_NOTSETINLANG = 6040,
  DW_LANGSTRING_SILENTLICENSE = 6049,
  DW_COMMENT_NEWLINE = 6050, // reserved ..6079
  DW_PLUGIN_NOUNLOAD_PLACEMENT = 6080, // reserved ..6099
  DW_PP_PRAGMA_UNKNOWN = 6100, // reserved ..6199
  DW_PP_PRAGMA_INVALID = 6101,
  DW_PP_DELFILE_DELERROR = 6149,
  DW_PP_DELFILE_NOMATCH = DW_PP_DELFILE_DELERROR,
  DW_PP_VERBOSE_POP_EMPTY_STACK = 6150,
  //DW_PP_VERBOSE_BAD_LEVEL = 6151?, // 2.x failed to issue a warning. 3.x currently aborts with hard error.
  DW_PP_UNDEF_UNDEFINED = 6155,
  DW_INCLUDE_NONFATAL_NOT_FOUND = 7000, // reserved ..7009
  DW_FILE_NONFATAL_NOT_FOUND = 7010, // reserved ..7019
  DW_LANGSTRING_OVERLONGLENGTH = 7020, // reserved ..7024
  DW_BAD_LANGID = 7025, // reserved ..7029
  DW_NLF_OLDVERSION = 7030, // reserved ..7049
  DW_NLF_SYSCP = 7031,
  DW_NLF_UNSUPPORTED_CP = 7032,
  DW_NLF_NOT_PREFERRED_ENC = 7033,
  DW_LICENSE_EMPTY = 7050,
  DW_ATTRIBUTE_OVERLONGSTRING = 7060,
  DW_PARSE_BADNUMBER = 7070,
  DW_PARSE_NUMBEROUTOFSPEC = 7071,
  DW_PARSE_LNK_HK = 7075,
  DW_GENERIC_DEPRECATED = 7998,
  DW_PARSE_REGPATHPREFIX = 7999,
  DW_INSTFILESPAGE_NOT_USED = 8000, // reserved ..8019
  DW_COMP_FINAL = 8020, // reserved ..8059
  DW_COMP_WHOLE_IGNORE_OFF = 8021,
  DW_COMP_LEVEL_IGNORE = 8025,
  DW_COMP_DICT_IGNORE = 8026,
  DW_COMP_DICTWHOLE = 8030,
  DW_CMDLINE_HIGHPRIORITY = 8499,
  DW_INSECURE_OUTFILENAME = 9000,
  DW_VI_MISSINGSTDKEY = 9100,
  DIAGCODE_INTERNAL_HIDEDIAGCODE = 9999,
  DIAGCODE_INTERNAL_FIRST = 1000, DIAGCODE_INTERNAL_LAST = 9999
} DIAGCODE;
#define PS_OK 0
#define PS_EOF 1
#define PS_ERROR 50
#define PS_WARNING 100
// token placement
#define TP_SEC    1
#define TP_FUNC   2
#define TP_CODE   (TP_SEC | TP_FUNC)
#define TP_GLOBAL 4
#define TP_PAGEEX 8
#define TP_PG     (TP_GLOBAL | TP_PAGEEX)
#define TP_ALL    (TP_CODE | TP_PG)
namespace MakensisAPI {
  extern const TCHAR* SigintEventNameFmt;
  extern const TCHAR* SigintEventNameLegacy;
  enum datatransfer_e {
    NOTIFY_SCRIPT, // Compiler -> Host: main nsi file(s)
    NOTIFY_WARNING,
    NOTIFY_ERROR,
    NOTIFY_OUTPUT, // Compiler -> Host: Generated .exe file
    PROMPT_FILEPATH // [0x03006000] Compiler -> Host -> Compiler
  };
#ifdef _WIN32
  enum sndmsg_e {
    QUERYHOST = WM_APP // [0x03000000] QUERYHOST_e in wParam. MUST return 0 for unknown QUERYHOST_e values!
  };
#endif
  enum QUERYHOST_e {
    QH_OUTPUTCHARSET = 1, // [0x03000000] return (wincodepage+1) or 0 for default (This encoding is used by stdout, stderr and the notify messages)
    QH_ENABLESTDERR, // [0x03001000] return 1 to output error messages to stderr or 0 to output error messages to stdout
    QH_SUPPORTEDVERSION, // [0x03006000] The host must return new highest makensis compiler version it supports
  };
  typedef struct {
    unsigned char Platform; // Bitness OR'ed with sizeof(TCHAR) of the compiler
    unsigned char Reserved;
    TCHAR Path[1];
  } PROMPT_FILEPATH_DATA;
}
#define PAGE_CUSTOM 0
#define PAGE_LICENSE 1
#define PAGE_COMPONENTS 2
#define PAGE_DIRECTORY 3
#define PAGE_INSTFILES 4
#define PAGE_UNINSTCONFIRM 5
#define PAGE_COMPLETED 6
#define FLAG_OFFSET(flag) (FIELD_OFFSET(exec_flags_t, flag)/sizeof(int))
class DiagState {
  template<class C, class K, class V> void insert_or_assign(C&c, const K&k, V val)
  {
    typename C::value_type item(k, val);
    std::pair<NSIS_CXX_TYPENAME C::iterator, bool> ret = c.insert(item);
    if (!ret.second) ret.first->second = val;
  }
  template<class C, class K> typename STL::mapped_type<C>::type get_paired_value(const C&c, const K&k, typename STL::mapped_type<C>::type defval) const
  {
    typename C::const_iterator it = c.find(k);
    return c.end() == it ? defval : it->second;
  }
  template<class T> int get_code_state(T t, int def) const { return get_paired_value(m_Warnings, static_cast<unsigned short>(t), def); }
public:
  typedef enum { wunspecified = -1, wdisabled = 0, wwarning, wenabled, werror } WARNSTATE;
  DiagState() : m_pStack(0), m_FallbackState(get_default_state()) { assert(DIAGCODE_INTERNAL_LAST <= 0xffff); }
  ~DiagState() { delete m_pStack; }
  static WARNSTATE get_default_state(DIAGCODE n = (DIAGCODE) 0) { return wenabled; } // All warnings currently default to enabled
  void def(DIAGCODE n) { insert_or_assign(m_Warnings, static_cast<unsigned short>(n), get_default_state(n)); }
  void enable(DIAGCODE n) { insert_or_assign(m_Warnings, static_cast<unsigned short>(n), wenabled); }
  void disable(DIAGCODE n) { insert_or_assign(m_Warnings, static_cast<unsigned short>(n), wdisabled); }
  void warning(DIAGCODE n) { insert_or_assign(m_Warnings, static_cast<unsigned short>(n), wwarning); } // Always !warning
  void error(DIAGCODE n) { insert_or_assign(m_Warnings, static_cast<unsigned short>(n), werror); } // Always !error
  bool is_disabled(DIAGCODE n) const { return get_code_state(n, m_FallbackState) == wdisabled; }
  bool is_error(DIAGCODE n) const { int s = get_code_state(n, m_FallbackState); return s == werror; }
  void push();
  bool pop();
  void set_all(WARNSTATE wm) { m_Warnings.clear(); m_FallbackState = wm; }
  void set_warning_as_error() { set_all(werror); }
  static bool is_valid_code(unsigned int n) { return n >= DIAGCODE_INTERNAL_FIRST && n <= DIAGCODE_INTERNAL_LAST; }
protected:
  DiagState *m_pStack;
  signed char m_FallbackState; // A fallback state so we don't have to fill the m_Warnings map with values for codes that are not explicitly set by the user
  std::map<unsigned short, signed char> m_Warnings;
};
class CEXEBuild {
  public:
    CEXEBuild(signed char pponly, bool warnaserror);
    void initialize(const TCHAR *makensis_path);
    ~CEXEBuild();
    enum {
      MAX_LINELENGTH = 16384, // NSI/NSH line limit, in TCHARs (including \0)
      MAX_MACRORECURSION = 50
    };
    static const TCHAR* get_commandlinecode_filename() { return _T("<command line>"); }
    void warning(DIAGCODE dc, const TCHAR *s, ...); // to add a warning to the compiler's warning list.
    void warning_fl(DIAGCODE dc, const TCHAR *s, ...); // warning with file name and line number
    void ERROR_MSG(const TCHAR *s, ...) const;
    void SCRIPT_MSG(const TCHAR *s, ...) const;
    void INFO_MSG(const TCHAR *s, ...) const;
    typedef enum {
      TARGETFIRST,
      TARGET_X86ANSI = TARGETFIRST,
      TARGET_X86UNICODE,
      TARGET_AMD64, // Always Unicode
      TARGET_ARM64, // Always Unicode
      TARGET_UNKNOWN,
      TARGETCOUNT = (TARGET_UNKNOWN-TARGETFIRST)
    } TARGETTYPE;
    TARGETTYPE m_target_type;
    TARGETTYPE get_target_type(const TCHAR*s) const;
    bool m_previous_x86_unicode;
    const TCHAR* get_target_suffix(CEXEBuild::TARGETTYPE tt, const TCHAR*defval = _T("?")) const;
    const TCHAR* get_target_suffix() const { return get_target_suffix(m_target_type); }
    static bool is_targettype_64bit(TARGETTYPE tt) { return TARGET_AMD64 == tt || TARGET_ARM64 == tt; }
    bool is_target_64bit() const { return is_targettype_64bit(m_target_type); }
    void print_bad_targettype_parameter(const TCHAR*cmdname, const TCHAR*prefix = _T("")) const;
    unsigned int get_header_size() const { return (unsigned int)sizeof(header) + (is_target_64bit() ? (4 * BLOCKS_NUM) : 0); }
    void set_default_output_filename(const tstring& filename);
    const TCHAR* get_output_filename() const { return build_output_filename; }
    // process a script (you can process as many scripts as you want,
    // it is as if they are concatenated)
    int process_script(NIStream&Strm, const TCHAR *filename);
    int process_oneline(const TCHAR *line, const TCHAR *curfilename, int lineptr);
    
    // you only get to call write_output once, so use it wisely.
    int write_output(void);
    void print_help(const TCHAR *commandname=NULL);
    bool print_cmdhelp(const TCHAR *commandname, bool cmdhelp=false);
    DefineList definedlist; // List of identifiers marked as "defined" like
                            // C++ macro definitions such as _UNICODE.
    void define(const TCHAR *p, const TCHAR *v=_T("")); // to add a defined thing.
    signed char preprocessonly; // > 0 = safe, < 0 = unsafe
    int get_verbosity() const;
    void set_verbosity(int lvl);
    bool display_errors;
    bool display_script;
    bool display_warnings;
    bool display_info;
    int linecnt;
    const TCHAR *curfilename;
    NStreamLineReader* curlinereader;
    HWND notify_hwnd;
    void notify(MakensisAPI::datatransfer_e code, const TCHAR *data) const;
    #ifdef _WIN32
    typedef bool (CALLBACK*HOSTAPIREQUESTDATAPROC)(void*cookie, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
    #else
    typedef bool (*HOSTAPIREQUESTDATAPROC)(void*cookie);
    #endif
    bool hostapi_request_data(MakensisAPI::datatransfer_e operation, UINT minver, HOSTAPIREQUESTDATAPROC proc, void*cookie, const void* input, size_t inputsize) const;
    bool prompt_for_output_path(TCHAR*path, UINT pathcap) const;
  private:
    int check_write_output_errors() const;
    int prepare_uninstaller();
    int pack_exe_header();
    int set_compressor(const tstring& compressor, const bool solid);
    int load_stub();
    int update_exehead(const tstring& file, size_t *size=NULL);
    void update_exehead(const unsigned char *new_exehead, size_t new_size);
    // tokens.cpp
    bool is_ppbranch_token(const TCHAR *s);
    bool is_pp_token(int tkid);
    bool is_unsafe_pp_token(int tkid);
    int get_commandtoken(const TCHAR *s, int *np, int *op, int *pos);
    const TCHAR* get_commandtoken_name(int tok);
    /**
     * Returns the current "state" by looking at whether it is in a
     * section/function/pagex or global.
     * @return TP_FUNC, TP_SEC, TP_PAGEEX, TP_GLOBAL.
     */
    int GetCurrentTokenPlace();
    int IsTokenPlacedRight(int pos, const TCHAR *tok);
    // script.cpp
#ifdef NSIS_SUPPORT_STANDARD_PREDEFINES
  // Added by Sunil Kamath 11 June 2003
    TCHAR* set_file_predefine(const TCHAR *);
    void restore_file_predefine(TCHAR *);
    TCHAR* set_timestamp_predefine(const TCHAR *);
    void restore_timestamp_predefine(TCHAR *);
    TCHAR* set_line_predefine(int, BOOL);
    void restore_line_predefine(TCHAR *);
    void set_date_time_predefines();
    void del_date_time_predefines();
#endif
    int parseScript();
    int includeScript(const TCHAR *f, NStreamEncoding&enc);
    TCHAR* GetMacro(const TCHAR *macroname, TCHAR**macroend = 0);
    bool MacroExists(const TCHAR *macroname) { return !!GetMacro(macroname); }
    LANGID ParseLangIdParameter(const LineParser&line, int token);
    int LoadLicenseFile(const TCHAR *file, TCHAR** pdata, const TCHAR *cmdname, WORD AnsiCP);
#ifdef NSIS_FIX_DEFINES_IN_STRINGS
    void ps_addtoline(const TCHAR *str, GrowBuf &linedata, StringList &hist, bool bIgnoreDefines = false);
#else
    void ps_addtoline(const TCHAR *str, GrowBuf &linedata, StringList &hist);
#endif
    int doParse(int verbosity, const TCHAR *fmt, ...);
    int doParse(const TCHAR *str);
    int doCommand(int which_token, LineParser &line);
    TCHAR m_templinebuf[MAX_LINELENGTH]; // Buffer used by parseScript() & doCommand(), not recursion safe!
    int add_flag_instruction_entry(int which_token, int opcode, LineParser &line, int offset, int data = 0);
    int do_add_file(const TCHAR *lgss, int attrib, int recurse, int *total_files, const TCHAR 
      *name_override=0, int generatecode=1, int *data_handle=0, 
      const std::set<tstring>& excluded=std::set<tstring>(), 
      const tstring& basedir=tstring(_T("")), bool dir_created=false);
    int add_file(const tstring& dir, const tstring& file, int attrib, const TCHAR 
      *name_override, int generatecode, int *data_handle);
    int do_add_file_create_dir(const tstring& local_dir, const tstring& dir, int attrib=0);
    GrowBuf m_linebuild; // used for concatenating lines
    // used by doParse to do preprocessing
    struct ifblock
    {
      int hasexeced;
      int elseused;
      int ignore;
      int inherited_ignore;
    } *cur_ifblock;
    TinyGrowBuf build_preprocessor_data;
    void start_ifblock();
    void end_ifblock();
    int num_ifblock();
    int last_line_had_slash;
    bool inside_comment;
    int multiple_entries_instruction;  // 1 (true) or 0 (false)
    int pp_macro(LineParser&line);
    int pp_macroundef(LineParser&line);
    int pp_insertmacro(LineParser&line);
    int pp_tempfile(LineParser&line);
    int pp_delfile(LineParser&line);
    int pp_appendfile(LineParser&line);
    int pp_getversionhelper(const TCHAR *cmdname, const TCHAR *path, const TCHAR *basesymname, DWORD high, DWORD low, DWORD flags);
    int pp_getversion(int which_token, LineParser&line);
    int pp_searchreplacestring(LineParser&line);
    int pp_searchparsestring(LineParser&line);
    DefineList *searchParseString(const TCHAR *source_string, LineParser&line, int parmOffs, bool ignCase, bool noErrors, UINT*failParam = 0);
    int pp_verbose(LineParser&line);
    int pp_define(LineParser&line);
    int pp_undef(LineParser&line);
    int pp_packhdr(LineParser&line);
    int pp_finalize(int which_token, LineParser&line);
    int pp_execute(int which_token, LineParser&line);
    int pp_addincludedir(LineParser&line);
    int pp_include(LineParser&line);
    int pp_cd(LineParser&line);
    int pp_pragma(LineParser&line);
    // build.cpp functions used mostly by script.cpp
    int set_target_architecture_data();
    int change_target_architecture(TARGETTYPE tt);
    void set_code_type_predefines(const TCHAR *value = NULL);
    int getcurdbsize();
    int add_section(const TCHAR *secname, const TCHAR *defname, int expand=0);
    int section_end();
    int add_function(const TCHAR *funname);
    int function_end();
    void section_add_size_kb(int kb);
    int section_add_flags(int flags);
    int section_add_install_type(int inst_type);
    int add_page(int type);
    int page_end();
    int add_label(const TCHAR *name);
    int add_entry(const entry *ent);
    int add_entry_direct(int which, int o0=0, int o1=0, int o2=0, int o3=0, int o4=0, int o5=0);
    int add_db_data(IMMap *map); // returns offset
    int add_db_data(const char *data, int length); // returns offset
    int add_db_data(const char *data, size_t length) { assert(length <= 0x7FFFFFFF); return add_db_data(data, (int)length); }
    int add_data(const char *data, int length, IGrowBuf *dblock); // returns offset
    int add_string(const TCHAR *string, int process=1, UINT codepage=-2); // returns offset (in string table)
    int add_asciistring(const TCHAR *string, int process=1); // For hardcoded 7bit/ASCII strings
    int add_intstring(const int i); // returns offset in stringblock
    int preprocess_string(TCHAR *out, const TCHAR *in, WORD codepage=CP_ACP);
    void init_shellconstantvalues();
    int parse_pragma(LineParser &line);
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
    int add_plugins_dir_initializer(void);
    int initialize_default_plugins(bool newtargetarc = false);
    Plugins m_plugins[TARGETCOUNT], *m_pPlugins;
    bool plugin_used;
    bool uninst_plugin_used;
    int build_plugin_unload; // TOK_SETPLUGINUNLOAD
#endif //NSIS_CONFIG_PLUGIN_SUPPORT
    // build.cpp functions used mostly within build.cpp
    int datablock_optimize(int start_offset, int first_int);
    bool datablock_finddata(IMMap&mmap, int mmstart, int size, int*ofs);
    void printline(int l);
    int process_jump(LineParser &line, int wt, int *offs);
    int AddVersionInfo();
    int ProcessPages();
    void PrepareInstTypes();
    void AddStandardStrings();
    void PrepareHeaders(IGrowBuf *hdrbuf);
    int SetVarsSection();
    int SetManifest();
    int UpdatePEHeader();
    int resolve_jump_int(const TCHAR *fn, int *a, int offs, int start, int end);
    int resolve_call_int(const TCHAR *fn, const TCHAR *str, int fptr, int *ofs);
    int resolve_instruction(const TCHAR *fn, const TCHAR *str, entry *w, int offs, int start, int end);
    int resolve_coderefs(const TCHAR *str);
    int uninstall_generate();
    void print_warnings();
    void warninghelper(DIAGCODE dc, bool fl, const TCHAR *fmt, va_list args);
    DiagState diagstate;
    bool changed_target;
    /** Are we defining an uninstall version of the code?
     * @param un Use like a boolean to define whether in uninstall mode.
     */
    void set_uninstall_mode(int un);
    // lang.cpp functions and variables
    void InitLangTables();
    /**
     * This function gets a LanguageTable structure for the specified language
     * via LANGID.  If create == true, it will create a new LanguageTable if
     * the appropriate one cannot be found.  If lang is LANG_NEUTRAL (0), then
     * it will get the LanguageTable of the last used language or more
     * correctly, the last Language ID that generated a valid return value
     * (not NULL).
     *
     * @param lang [in/out] Language ID reference.  If LANG_NEUTRAL, it gets
     * set to thelast used language ID.
     * @param create Create a new LanguageTable?  Default = true.
     * @return Appropriate LanguagTable* if exists, otherwise NULL.
     */
    LanguageTable *GetLangTable(LANGID &lang, bool create = true);
    /**
      * Get the language name as a TCHAR* and the code page value via an
      * out parameter.  It will look for a LanguageTable to get the values.
      * If not found, then it will set the codepage to English for ANSI
      * or Unicode for Unicode version of NSIS.  The language name is looked
      * up via the LanguageTable if it exists, otherwise, it returns "???" except 
      * a hardcoded check for 1033 (english). It really should fall back to 
      * calling GetLocaleInfo() with the LANGID to get the string.
      *
      * This function is not thread-safe!  For a thread-safe version, the
      * parameter must include the buffer to write to.
      *
      * @param lang The language ID
      * @param codepage [out] The code page referred to by the language ID.
      * @return The language string in English.
      */
    const TCHAR *GetLangNameAndCP(LANGID lang, unsigned int *codepage = NULL);
    const TCHAR *GetLangNameAndCPForVersionResource(LANGID &lang, unsigned int *codepage = NULL, bool deflangfallback = true);
    int DefineLangString(const TCHAR *name, int process=-1);
    int DefineInnerLangString(int id, int process=-1);
    /**
     * A LangString is a string variable that varies in value depending on what
     * language is being used.  This function sets the string value for the
     * variable 'name' for a given language ID.
     * 
     * @return If the language id, the variable name or string is invalid, it will
     * return a PS_ERROR.  If this function call is overwriting a set user string,
     * this will return a PS_WARNING.
     */
    int SetLangString(const TCHAR *name, LANGID lang, const TCHAR *str, BOOL LicenseData);
    int SetLangString(const TCHAR *name, LANGID lang, const TCHAR *str);
    /**
     * Sets the user string to the specific NLF_STRINGS id.
     *
     * @return If the id is invalid or the string is not valid, it will return
     * a PS_ERROR.  If this function call is overwriting a set user string,
     * this will return a PS_WARNING.
     */
    int SetInnerString(int id, const TCHAR *str);
    int GenerateLangTable(LanguageTable *lt, int num_lang_tables);
    int GenerateLangTables();
    void FillLanguageTable(LanguageTable *table);
    int HasUserDefined(int id) {
      const TCHAR *us = UserInnerStrings.get(id);
      return us && *us;
    };
    LanguageTable *LoadLangFile(TCHAR *filename);
    void DeleteLangTable(LanguageTable *table);
    NLFRef NLFRefs[NLF_STRINGS];
    bool keep_ref;
    StringsArray UserInnerStrings;
    bool defcodepage_set;
    GrowBuf lang_tables;
    LANGID last_used_lang;
    LangStringList build_langstrings;
    int build_langstring_num, ubuild_langstring_num;
    TCHAR build_font[1024];
    int build_font_size;
    unsigned int uDefCodePage;
    // pages stuff
    int license_res_id;
    page *cur_page;  // Current page we are defining, NULL if not.
    int cur_page_type;
    int enable_last_page_cancel, uenable_last_page_cancel;
    int disable_window_icon;
    // User variables stuff
    int GetUnsafeUserVarIndex(LineParser &line, int token);
    int GetUserVarIndex(LineParser &line, int token);
    // Added by ramon 3 jun 2003
    UserVarsStringList m_UserVarNames;
    int m_iBaseVarsNum;
    int DeclaredUserVar(const TCHAR *VarName);
    void VerifyDeclaredUserVarRefs(UserVarsStringList *pVarsStringList);
    bool IsIntOrUserVar(const LineParser &line, int token) const;
    static bool IsVarPrefix(const TCHAR*s) { return *s++ == _T('$') && *s > ' '; }
    ConstantsStringList m_ShellConstants;
    // a whole bunch O data.
    tstring stubs_dir;
    tstring stub_filename;
#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
    ICompressor *compressor;
    CZlib zlib_compressor;
    CBzip2 bzip2_compressor;
    CLZMA lzma_compressor;
#endif
    bool build_compressor_set;
    bool build_compressor_final;
    bool build_compress_whole;
    int build_compress;
    int build_compress_level;
    int build_compress_dict_size;
    bool no_space_texts;
    bool build_unicode;// generate installer with unicode exehead?
    bool build_lockedunicodetarget;
    class writer_target_info mk_writer_target_info();
    bool has_called_write_output;
    struct postbuild_cmd
    {
      struct postbuild_cmd*next;
      int cmpop, cmpval;
      TCHAR cmd[1];
      void delete_all();
      static postbuild_cmd* make(const TCHAR *cmdstr, int cmpop, int cmpval);
    } *postbuild_cmds, *postubuild_cmds;
    int run_postbuild_cmds(const postbuild_cmd *cmds, const TCHAR *templatearg_pc1, const TCHAR* commandname);
    int check_external_exitcode(int exitcode, int op, int val);
    TCHAR build_packname[1024], build_packcmd[1024];
    int build_overwrite, build_last_overwrite, build_crcchk,
        build_datesave, build_optimize_datablock,
        build_allowskipfiles; // Added by ramon 23 May 2003
    header build_header, build_uninst, *cur_header;
    int uninstall_mode; // Are we in uninstall mode?  Acts like a bool.
    int uninstall_size,uninstall_size_full;
    int uninstaller_writes_used;
    TCHAR build_output_filename[1024];
    int build_include_depth;
    // Added by ramon 6 jun 2003
#ifdef NSIS_SUPPORT_VERSION_INFO
    CResourceVersionInfo rVersionInfo;
    unsigned int version_fixedflags;
#endif
    int sectiongroup_open_cnt;
    FastStringList m_warnings;
    const TCHAR* m_currentmacroname;
    GrowBuf m_macros;
    UINT64 db_opt_save, db_opt_save_u, db_full_size, db_full_size_u;
    int db_comp_save, db_comp_save_u;
    FastStringList include_dirs;
    StringList ns_func; // function namespace
    StringList ns_label; // label namespace
    int build_cursection_isfunc; // Are we in the middle of func definition?
    section *build_cursection;   // The section we are defining, NULL if not in section.
                                 // This could be a function or a section.
    // The ubuild prefixed objects / variables are for the uninstall versions
    // of the code.  The cur prefix objects are what the current objects that
    // need to be referenced should be.  What is pointed to by the cur* objects
    // are determined by whether or not we are in uninstall mode or not.
    TinyGrowBuf build_sections, ubuild_sections, *cur_sections;
    GrowBuf build_entries,ubuild_entries, *cur_entries;
    GrowBuf build_instruction_entry_map,ubuild_instruction_entry_map, *cur_instruction_entry_map;
    TinyGrowBuf build_functions, ubuild_functions, *cur_functions;
    TinyGrowBuf build_labels, ubuild_labels, *cur_labels;
    ExeHeadStringList build_strlist, ubuild_strlist, *cur_strlist;
    GrowBuf build_langtables, ubuild_langtables, *cur_langtables;
    TinyGrowBuf build_pages, ubuild_pages, *cur_pages;
    TinyGrowBuf build_ctlcolors, ubuild_ctlcolors, *cur_ctlcolors;
    // don't forget to update the cache after updating the datablock
    // see datablock_optimize for an example
    MMapBuf build_datablock, ubuild_datablock;
    TinyGrowBuf build_datablock_cache, ubuild_datablock_cache;
    IGrowBuf *cur_datablock, *cur_datablock_cache;
    struct cached_db_size
    {
      int first_int; // size | (compressed ? 0x80000000 : 0)
      int start_offset;
    };
    int build_filebuflen;
    TinyGrowBuf verbose_stack;
    unsigned char *m_exehead;
    size_t m_exehead_size;
    size_t m_exehead_original_size;
    bool branding_image_found;
    WORD branding_image_id;
    IconGroup installer_icon;
    IconGroup uninstaller_icon;
    size_t m_unicon_size;
#ifdef NSIS_SUPPORT_BGBG
    LOGFONT bg_font;
    LOGFONT bg_default_font;
#endif
#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
    int deflateToFile(FILE *fp, char *buf, int len); // len==0 to flush
#endif
    WORD PEDllCharacteristics, PESubsysVerMaj, PESubsysVerMin;
    unsigned int manifest_flags;
    manifest::comctl manifest_comctl;
    manifest::exec_level manifest_exec_level;
    manifest::dpiaware manifest_dpiaware;
    tstring manifest_dpiawareness;
    manifest::longpathaware manifest_lpaware;
    manifest::SupportedOSList manifest_sosl;
    tstring manifest_maxversiontested;
    CResourceEditor *res_editor;
    void init_res_editor();
    void close_res_editor();
};
#endif //_BUILD_H_
 
     |