+ Sections can be unselected in silent mode too

+ Some documentation fixes
+ Transition between a normal page and a custom page no longer causes a flicker (between two custom pages it still does)
+ The completed sub-caption shows again


git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@1853 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
kichik 2002-11-30 13:15:49 +00:00
parent e34ad8ec8d
commit 5e9ede6d31
15 changed files with 209 additions and 203 deletions

View file

@ -1004,8 +1004,8 @@ void showCfgDlg()
lpWndProcOld = (void *) SetWindowLong(hMainWindow,GWL_WNDPROC,(long)ParentWndProc);
ShowWindow(hConfigWindow, SW_SHOWNA);
SetFocus(hNextButton);
InvalidateRect(hConfigWindow,0,0);
SetFocus(hNextButton);
LockWindowUpdate(0);
g_done=0;

View file

@ -94,8 +94,6 @@ void __declspec(dllexport) Select(HWND hwndParent, int string_size, char *variab
lpWndProcOld = (void *) SetWindowLong(hwndParent, GWL_WNDPROC, (long) ParentWndProc);
}
//LockWindowUpdate(0);
while (!g_done)
{
MSG msg;
@ -254,7 +252,9 @@ BOOL CALLBACK dlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
AddFolderFromReg(HKEY_CURRENT_USER);
ShowWindow(hwndDlg, SW_SHOWNA);
InvalidateRect(hwndDlg,0,0);
SetFocus(GetDlgItem(hwParent, IDOK));
LockWindowUpdate(0);
}
break;
case WM_COMMAND:

View file

@ -140,7 +140,7 @@ This attribute tells the installer to check a string in the registry, and use it
\c [flag [...]]
Valid values for flag are "smooth" (smooth the progress bar) or "colored" (color the progress bar with the colors set by InstallColors. Examples: "InstProgressFlags" (default old-school windows look), "InstProgressFlags smooth" (new smooth look), "InstProgressFlags smooth colored" (colored smooth look whee).
Valid values for flag are "smooth" (smooth the progress bar) or "colored" (color the progress bar with the colors set by InstallColors. Examples: "InstProgressFlags" (default old-school windows look), "InstProgressFlags smooth" (new smooth look), "InstProgressFlags smooth colored" (colored smooth look whee). Note: neither "smooth" or "colored" work with XPStyle on (see \k{axpstyle}).
\S2{ainsttype} InstType
@ -226,13 +226,13 @@ Sets whether or not the details of the uninstall are shown. Can be 'hide' to hid
\c \\<b\\>normal\\</b\\>|silent|silentlog
Specifies whether or not the installer should be silent. If it is 'silent' or 'silentlog', all sections are installed quietly, with no screen output from the installer itself (MessageBoxes are still displayed on error, and the script can still display whatever it wants). Note that if this is set to 'normal' and the user runs the installer with /S on the command line, it will behave as if SilentInstall 'silent' was used. Note: see also LogSet (\k{logset}).
Specifies whether or not the installer should be silent. If it is 'silent' or 'silentlog', all sections that have the SF_SELECTED flag are installed quietly (you can set this flag using SectionSetFlags [see \k{sectionsetflags}]), with no screen output from the installer itself (MessageBoxes are still displayed on error, and the script can still display whatever it wants). Note that if this is set to 'normal' and the user runs the installer with /S on the command line, it will behave as if SilentInstall 'silent' was used. Note: see also LogSet (\k{logset}).
\S2{asilentuninstall} SilentUnInstall
\c \\<b\\>normal\\</b\\>|silent
Specifies whether or not the uninstaller should be silent. If it is 'silent' or 'silentlog', all sections are installed quietly, with no screen output from the installer itself (MessageBoxes are still displayed on error, and the script can still display whatever it wants). Note that if this is set to 'normal' and the user runs the installer with /S on the command line, it will behave as if SilentInstall 'silent' was used. Note: see also LogSet (\k{logset}).
Specifies whether or not the uninstaller should be silent. If it is 'silent' or 'silentlog', the uninstall section will run quietly, with no screen output from the uninstaller itself (MessageBoxes are still displayed on error, and the script can still display whatever it wants). Note that if this is set to 'normal' and the user runs the uninstaller with /S on the command line, it will behave as if SilentUnInstall 'silent' was used. Note: see also LogSet (\k{logset}).
\S2{aspacetexts} SpaceTexts

View file

@ -10,6 +10,8 @@
\b New easier version of the Modern User Interface with better multilanguage support, InstallOptions integration, welcome and finish page etc.
\b Custom pages no longer flicker when created
\b Added accelerator keys
\b Added LangString and LangStringUP for user defined multilingual strings
@ -24,7 +26,7 @@
\b Splash.exe is now a plugin (splash.dll)
\b Added new plugins: System, AdvSplash, nsExec, UserInfo, BgImage and StartMenu
\b Added new plugins: System, AdvSplash, nsExec, UserInfo, BgImage, Banner and StartMenu
\b !ifdef and friends can now be used in macros

View file

@ -1,6 +1,6 @@
\S1{secmanage} Section Management
\S2{SectionSetFlags} SectionSetFlags
\S2{sectionsetflags} SectionSetFlags
\c section_index section_flags
@ -8,19 +8,19 @@ Sets the section's flags. The flag is a 32 bit integer. The first bit (lowest) r
For an example of usage please see the \W{../Examples/one-section.nsi}{one-section.nsi} example.
\S2{SectionGetFlags} SectionGetFlags
\S2{sectiongetflags} SectionGetFlags
\c section_index user_var(output)
Retrieves the section's flags. See above for a description of the flag. The error flag will be set if an out of range section is specified.
\S2{SectionSetText} SectionSetText
\S2{sectionsettext} SectionSetText
\c section_index section_text
Sets the description for the section section_index. To set a subsection, you must use - at the beginning of the text. The error flag will be set if an out of range section is specified.
\S2{SectionGetText} SectionGetText
\S2{sectiongettext} SectionGetText
\c section_index user_var(output)

Binary file not shown.

Binary file not shown.

View file

@ -50,10 +50,6 @@ char g_caption[NSIS_MAX_STRLEN*2];
int g_filehdrsize;
HWND g_hwnd;
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
extern char plugins_temp_dir[NSIS_MAX_STRLEN];
#endif
int m_length;
int m_pos;
@ -106,6 +102,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,LPSTR lpszCmdParam,
char seekchar=' ';
InitCommonControls();
GetTempPath(sizeof(temp_directory), temp_directory);
lstrcpyn(state_command_line,GetCommandLine(),NSIS_MAX_STRLEN);
if (*cmdline == '\"') seekchar = *cmdline++;
@ -303,7 +302,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,LPSTR lpszCmdParam,
static char ibuf[NSIS_MAX_STRLEN];
buf2[0]='\"';
GetTempPath(sizeof(buf2)-1,buf2+1);
mystrcpy(buf2+1,temp_directory);
lstrcat(buf2,s);
DeleteFile(buf2+1); // clean up after all the other ones if they are there
@ -330,8 +329,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst,LPSTR lpszCmdParam,
lstrcat(buf2,realcmds);
lstrcat(buf2," _?=");
lstrcat(buf2,ibuf);
GetTempPath(sizeof(ibuf),ibuf);
hProc=myCreateProcess(buf2,ibuf);
hProc=myCreateProcess(buf2,temp_directory);
if (hProc) CloseHandle(hProc);
else m_Err = g_errorcopyinginstall;
}

View file

@ -134,7 +134,7 @@ static BOOL NSISCALL _HandleStaticBkColor(UINT uMsg, WPARAM wParam, LPARAM lPara
}
return 0;
}
#else//NSIS_CONFIG_ENHANCEDUI_SUPPORT
#else
#define HandleStaticBkColor() 0
#endif//!NSIS_CONFIG_ENHANCEDUI_SUPPORT
@ -207,7 +207,7 @@ static void NSISCALL SetParentState(HWND hWnd, TV_ITEM *pItem) {
if (iState)
{
if (iState==5) iState=2;
else if (iState==4) iState=1;
if (iState==4) iState=1;
if (iStatePrev && (iStatePrev != iState)) {
iState = 3;
break;
@ -279,7 +279,7 @@ lang_again:
myitoa(state_language, *(LANGID*)language_table);
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
SendMessage(m_bgwnd, WM_SETTEXT, 0, (LPARAM)process_string_fromtab(g_caption,LANG_CAPTION));
SetWindowText(m_bgwnd,process_string_fromtab(g_caption,LANG_CAPTION));
#endif
}
@ -361,7 +361,7 @@ int NSISCALL ui_doinstall(void)
if (!g_inst_cmnheader->silent_install)
#endif//NSIS_CONFIG_SILENT_SUPPORT
{
g_hIcon=LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_ICON2));
g_hIcon=LoadImage(g_hInstance,MAKEINTRESOURCE(IDI_ICON2),IMAGE_ICON,0,0,LR_DEFAULTSIZE|LR_SHARED);
m_bgwnd=GetDesktopWindow();
#ifdef NSIS_SUPPORT_BGBG
if (g_inst_cmnheader->bg_color1 != -1)
@ -373,7 +373,7 @@ int NSISCALL ui_doinstall(void)
wc.lpfnWndProc = BG_WndProc;
wc.hInstance = g_hInstance;
wc.hIcon = g_hIcon;
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
//wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.lpszClassName = "_Nb";
if (!RegisterClass(&wc)) return 0;
@ -505,7 +505,7 @@ BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
this_page=g_inst_page+m_page;
// if the last page was a custom page, wait for it to finish by itself.
// if it doesn't, it's a bad plugin.
// if it doesn't, it's a BAD plugin.
// plugins should react to WM_NOTIFY_OUTER_NEXT.
if (m_page>=0&&this_page->id<0) return 0;
@ -527,7 +527,12 @@ nextPage:
{
HWND hwndtmp;
//LockWindowUpdate(g_hwnd);
#ifdef NSIS_SUPPORT_CODECALLBACKS
// lock display for custom pages to prevent flickering
// the custom page must unlock the display
if (this_page->id<0) LockWindowUpdate(hwndDlg);
else LockWindowUpdate(0);
#endif
SetDlgItemTextFromLang(hwndDlg,IDOK,this_page->next);
@ -536,21 +541,20 @@ nextPage:
EnableWindow(hwndtmp,this_page->back&2);
EnableWindow(m_hwndOK,1);
mystrcpy(g_tmp,g_caption);
process_string_fromtab(g_tmp+mystrlen(g_tmp),this_page->caption);
SetWindowText(hwndDlg,g_tmp);
if (this_page->id!=NSIS_PAGE_COMPLETED) DestroyWindow(m_curwnd);
else {
if (g_autoclose) goto nextPage;
return 0;
}
mystrcpy(g_tmp,g_caption);
process_string_fromtab(g_tmp+mystrlen(g_tmp),this_page->caption);
SetWindowText(hwndDlg,g_tmp);
#ifdef NSIS_SUPPORT_CODECALLBACKS
if (ExecuteCodeSegment(this_page->prefunc,NULL) || this_page->id<0)
goto nextPage;
#endif //NSIS_SUPPORT_CODECALLBACKS
//LockWindowUpdate(0);
if (this_page->id>=0) // NSIS page
{
gDontFookWithFocus = 0;
@ -564,8 +568,8 @@ nextPage:
#ifdef NSIS_SUPPORT_CODECALLBACKS
ExecuteCodeSegment(this_page->postfunc,NULL);
#endif //NSIS_SUPPORT_CODECALLBACKS
SendMessage(m_curwnd, WM_NOTIFY_START, 0, 0);
ShowWindow(m_curwnd,SW_SHOWNA);
SendMessage(m_curwnd, WM_NOTIFY_START, 0, 0);
}
//XGE 5th September 2002 - Do *not* move the focus to the OK button if we are
@ -577,6 +581,14 @@ nextPage:
}
}
}
if (uMsg == WM_CLOSE)
{
if (!IsWindowEnabled(m_hwndCancel) && IsWindowEnabled(m_hwndOK))
{
uMsg = WM_COMMAND;
wParam = IDOK;
}
}
if (uMsg == WM_COMMAND)
{
int id=LOWORD(wParam);
@ -611,11 +623,6 @@ nextPage:
}
}
}
if (uMsg == WM_CLOSE)
{
if (!IsWindowEnabled(m_hwndCancel) && IsWindowEnabled(m_hwndOK))
SendMessage(hwndDlg,WM_COMMAND,IDOK,0);
}
return HandleStaticBkColor();
}
@ -652,7 +659,7 @@ static BOOL CALLBACK LicenseProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
return FALSE;
//End Xge
}
else if (uMsg == WM_NOTIFY) {
if (uMsg == WM_NOTIFY) {
#define nmhdr ((NMHDR *)lParam)
#define enlink ((ENLINK *)lParam)
#define msgfilter ((MSGFILTER *)lParam)
@ -668,7 +675,7 @@ static BOOL CALLBACK LicenseProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
SetCursor(LoadCursor(0,IDC_ARROW));
GlobalFree(szUrl);
}
else if (enlink->msg==WM_SETCURSOR) {
if (enlink->msg==WM_SETCURSOR) {
#ifndef IDC_HAND
#define IDC_HAND MAKEINTRESOURCE(32649)
#endif
@ -680,7 +687,7 @@ static BOOL CALLBACK LicenseProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
//push button. When the user presses return ask the outer dialog to move
//the installer onto the next page. MSDN docs say return non-zero if the
//rich edit control should NOT process this message, hence the return 1.
else if (nmhdr->code==EN_MSGFILTER)
if (nmhdr->code==EN_MSGFILTER)
{
if (msgfilter->msg==WM_KEYDOWN &&
msgfilter->wParam==VK_RETURN)
@ -689,8 +696,11 @@ static BOOL CALLBACK LicenseProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
return 1;
}
}
#undef nmhdr
#undef enlink
#undef msgfilter
}
else if (uMsg == WM_CLOSE) {
if (uMsg == WM_CLOSE) {
SendMessage(g_hwnd,WM_CLOSE,0,0);
}
return HandleStaticBkColor();
@ -753,7 +763,7 @@ static BOOL CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
int id=LOWORD(wParam);
if (id == IDC_DIR && HIWORD(wParam) == EN_CHANGE)
{
SendMessage(hwndDlg,WM_IN_UPDATEMSG,0,0);
uMsg = WM_IN_UPDATEMSG;
}
if (id == IDC_BROWSE)
{
@ -1057,7 +1067,9 @@ static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
tv.pszText=process_string_fromtab(ps_tmpbuf,ns);
TreeView_SetItem(hwndTree1,&tv);
}
SendMessage(hwndDlg,WM_USER+0x18,x,(LPARAM)(g_inst_section[x].flags&SF_SELECTED));
uMsg = WM_USER+0x18;
wParam = x;
lParam = (LPARAM)(g_inst_section[x].flags&SF_SELECTED);
}
if (uMsg == WM_USER+0x18) // select
{
@ -1146,12 +1158,12 @@ static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
m_whichcfg=r;
}
} // end of typecheckshit
SendMessage(hwndDlg,WM_IN_UPDATEMSG,0,0);
uMsg = WM_IN_UPDATEMSG;
} // not ro
} // was valid click
} // was click or hack
#if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT)
else if (lpnmh->code == TVN_SELCHANGED) {
if (lpnmh->code == TVN_SELCHANGED) {
SendMessage(hwndTree1, WM_USER+0x19, 0, ((LPNMTREEVIEW)lpnmh)->itemNew.lParam);
}
#endif//NSIS_SUPPORT_CODECALLBACKS && NSIS_CONFIG_ENHANCEDUI_SUPPORT
@ -1200,7 +1212,7 @@ static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
}
SendMessage(hwndTree1,WM_VSCROLL,SB_TOP,0);
}
SendMessage(hwndDlg,WM_IN_UPDATEMSG,0,0);
uMsg = WM_IN_UPDATEMSG;
}
}
}
@ -1266,7 +1278,6 @@ void NSISCALL update_status_text(const char *text1, const char *text2)
static DWORD WINAPI install_thread(LPVOID p)
{
HWND hwndDlg=(HWND)p;
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
if (g_is_uninstaller)
{
@ -1279,11 +1290,7 @@ static DWORD WINAPI install_thread(LPVOID p)
while (m_inst_sec<num_sections && !m_abort)
{
#ifdef NSIS_CONFIG_COMPONENTPAGE
if (g_inst_section[m_inst_sec].flags&SF_SELECTED
#ifdef NSIS_CONFIG_SILENT_SUPPORT
|| g_inst_cmnheader->silent_install
#endif//NSIS_CONFIG_SILENT_SUPPORT
)
if (g_inst_section[m_inst_sec].flags&SF_SELECTED)
#endif
{
log_printf2("Section: \"%s\"",GetStringFromStringTab(g_inst_section[m_inst_sec].name_ptr));
@ -1300,7 +1307,7 @@ static DWORD WINAPI install_thread(LPVOID p)
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
}
#endif
if (hwndDlg) SendMessage(hwndDlg,WM_NOTIFY_INSTPROC_DONE,m_abort,0);
if (m_curwnd) SendMessage(m_curwnd,WM_NOTIFY_INSTPROC_DONE,m_abort,0);
return m_abort;
}
@ -1371,7 +1378,7 @@ static BOOL CALLBACK InstProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
}
if (uMsg == WM_NOTIFY_START) {
DWORD id;
CloseHandle(CreateThread(NULL,0,install_thread,(LPVOID)hwndDlg,0,&id));
CloseHandle(CreateThread(NULL,0,install_thread,0,0,&id));
}
if (uMsg == WM_COMMAND && LOWORD(wParam) == IDC_SHOWDETAILS)
{

View file

@ -379,7 +379,7 @@ static int NSISCALL ExecuteEntry(entry *entry_)
case EW_GETTEMPFILENAME:
{
char *textout=var0;
if (!GetTempPath(NSIS_MAX_STRLEN,buf0) || !GetTempFileName(buf0,"nst",0,textout))
if (!GetTempFileName(temp_directory,"nst",0,textout))
{
exec_errorflag++;
*textout=0;

View file

@ -67,9 +67,8 @@ const char * NSISCALL loadHeaders(void)
inflateReset(&g_inflate_stream);
{
char fn[MAX_PATH],fno[MAX_PATH];
GetTempPath(sizeof(fn),fn);
GetTempFileName(fn,"nsi",0,fno);
char fno[MAX_PATH];
GetTempFileName(temp_directory,"nst",0,fno);
dbd_hFile=CreateFile(fno,GENERIC_WRITE|GENERIC_READ,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE,NULL);
if (dbd_hFile == INVALID_HANDLE_VALUE)
{

View file

@ -1,3 +1,8 @@
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
extern char plugins_temp_dir[NSIS_MAX_STRLEN];
#endif
extern char temp_directory[NSIS_MAX_STRLEN];
extern char g_usrvars[25][NSIS_MAX_STRLEN];
// changed by Amir Szekely 28th August 2002
// smaller exehead

View file

@ -12,9 +12,7 @@
char g_log_file[1024];
#endif
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
extern char plugins_temp_dir[NSIS_MAX_STRLEN];
#endif
char temp_directory[NSIS_MAX_STRLEN];
char g_usrvars[25][NSIS_MAX_STRLEN];
char *state_command_line=g_usrvars[20];
@ -25,6 +23,10 @@ char *state_language=g_usrvars[24];
HANDLE g_hInstance;
#ifndef INVALID_FILE_ATTRIBUTES
#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
#endif
HANDLE NSISCALL myCreateProcess(char *cmd, char *dir)
{
DWORD d;
@ -326,7 +328,7 @@ static void NSISCALL queryShellFolders(const char *name_, char *out)
{
f=0; goto again;
}
GetTempPath(NSIS_MAX_STRLEN,out);
mystrcpy(out,temp_directory);
}
}
}
@ -477,7 +479,7 @@ char * NSISCALL process_string(char *out, const char *in)
}
case VAR_CODES_START + 32: // TEMP
GetTempPath(NSIS_MAX_STRLEN, out);
mystrcpy(out,temp_directory);
break;
case VAR_CODES_START + 33: // WINDIR
@ -547,4 +549,4 @@ void NSISCALL log_write(int close)
}
#endif
#endif

View file

@ -411,7 +411,7 @@ void CEXEBuild::FillDefaultsIfNeeded(StringTable *table, NLF *nlf/*=0*/) {
if (!table->common.subcaptions[3])
table->common.subcaptions[3]=add_string_main(str(NLF_SUBCAPTION_INSTFILES));
if (!table->common.subcaptions[4])
table->common.subcaptions[4]=add_string_main(str(NLF_USUBCAPTION_COMPLETED));
table->common.subcaptions[4]=add_string_main(str(NLF_SUBCAPTION_COMPLETED));
if (!table->common.branding)
{

View file

@ -154,143 +154,6 @@ local int __myleave(z_streamp z, int r, int b, int k, Bytef *p, int n, Bytef *q)
return inflate_flush(z,r);
}
local __inline int inflate_codes(z, r)
z_streamp z;
int r;
{
inflate_blocks_statef *s=&z->blocks;
uInt j; /* temporary storage */
inflate_huft *t; /* temporary pointer */
uInt e; /* extra bits or operation */
uLong b; /* bit buffer */
uInt k; /* bits in bit buffer */
Bytef *p; /* input data pointer */
uInt n; /* bytes available there */
Bytef *q; /* output window write pointer */
uInt m; /* bytes to end of window or read pointer */
Bytef *f; /* pointer to copy strings from */
inflate_codes_statef *c = &s->sub.decode.t_codes; /* codes state */
/* copy input/output information to locals (UPDATE macro restores) */
LOAD
/* process input and output based on current state */
while (1) switch (c->mode)
{ /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
case START: /* x: set up for LEN */
c->sub.code.need = c->lbits;
c->sub.code.tree = c->ltree;
c->mode = LEN;
case LEN: /* i: get length/literal/eob next */
j = c->sub.code.need;
NEEDBITS(j)
t = c->sub.code.tree + ((uInt)b & (uInt)inflate_mask[j]);
DUMPBITS(t->bits)
e = (uInt)(t->exop);
if (e == 0) /* literal */
{
c->sub.lit = t->base;
c->mode = LIT;
break;
}
if (e & 16) /* length */
{
c->sub.copy.get = e & 15;
c->len = t->base;
c->mode = LENEXT;
break;
}
if ((e & 64) == 0) /* next table */
{
c->sub.code.need = e;
c->sub.code.tree = t + t->base;
break;
}
if (e & 32) /* end of block */
{
c->mode = WASH;
break;
}
goto badcode;
case LENEXT: /* i: getting length extra (have base) */
j = c->sub.copy.get;
NEEDBITS(j)
c->len += (uInt)b & (uInt)inflate_mask[j];
DUMPBITS(j)
c->sub.code.need = c->dbits;
c->sub.code.tree = c->dtree;
c->mode = DIST;
case DIST: /* i: get distance next */
j = c->sub.code.need;
NEEDBITS(j)
t = c->sub.code.tree + ((uInt)b & (uInt)inflate_mask[j]);
DUMPBITS(t->bits)
e = (uInt)(t->exop);
if (e & 16) /* distance */
{
c->sub.copy.get = e & 15;
c->sub.copy.dist = t->base;
c->mode = DISTEXT;
break;
}
if ((e & 64) == 0) /* next table */
{
c->sub.code.need = e;
c->sub.code.tree = t + t->base;
break;
}
goto badcode;
// c->mode = BADCODE; /* invalid code */
// r = Z_DATA_ERROR;
// LEAVE
case DISTEXT: /* i: getting distance extra */
j = c->sub.copy.get;
NEEDBITS(j)
c->sub.copy.dist += (uInt)b & (uInt)inflate_mask[j];
DUMPBITS(j)
c->mode = COPY;
case COPY: /* o: copying bytes in window, waiting for space */
f = (uInt)(q - s->window) < c->sub.copy.dist ?
s->end - (c->sub.copy.dist - (q - s->window)) :
q - c->sub.copy.dist;
while (c->len)
{
NEEDOUT
OUTBYTE(*f++)
if (f == s->end)
f = s->window;
c->len--;
}
c->mode = START;
break;
case LIT: /* o: got literal, waiting for output space */
NEEDOUT
OUTBYTE(c->sub.lit)
c->mode = START;
break;
case WASH: /* o: got eob, possibly more output */
if (k > 7) /* return unused byte, if any */
{
k -= 8;
n++;
p--; /* can always return one */
}
FLUSH
if (s->read != s->write)
LEAVE
c->mode = END;
case END:
r = Z_STREAM_END;
LEAVE
default:
badcode:
r = Z_STREAM_ERROR;
LEAVE
}
}
#define BMAX 15 /* maximum bit length of any code */
local int huft_build(
@ -731,7 +594,137 @@ int r=Z_OK;
s->mode = CODES;
case CODES:
UPDATE
if ((r = inflate_codes(z, r)) != Z_STREAM_END)
{
inflate_huft *j; /* temporary pointer */
uInt e; /* extra bits or operation */
Bytef *f; /* pointer to copy strings from */
inflate_codes_statef *c = &s->sub.decode.t_codes; /* codes state */
int done = 0;
/* process input and output based on current state */
while (!done) switch (c->mode)
{ /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
case START: /* x: set up for LEN */
c->sub.code.need = c->lbits;
c->sub.code.tree = c->ltree;
c->mode = LEN;
case LEN: /* i: get length/literal/eob next */
t = c->sub.code.need;
NEEDBITS(t)
j = c->sub.code.tree + ((uInt)b & (uInt)inflate_mask[t]);
DUMPBITS(j->bits)
e = (uInt)(j->exop);
if (e == 0) /* literal */
{
c->sub.lit = j->base;
c->mode = LIT;
break;
}
if (e & 16) /* length */
{
c->sub.copy.get = e & 15;
c->len = j->base;
c->mode = LENEXT;
break;
}
if ((e & 64) == 0) /* next table */
{
c->sub.code.need = e;
c->sub.code.tree = j + j->base;
break;
}
if (e & 32) /* end of block */
{
c->mode = WASH;
break;
}
goto badcode;
case LENEXT: /* i: getting length extra (have base) */
t = c->sub.copy.get;
NEEDBITS(t)
c->len += (uInt)b & (uInt)inflate_mask[t];
DUMPBITS(t)
c->sub.code.need = c->dbits;
c->sub.code.tree = c->dtree;
c->mode = DIST;
case DIST: /* i: get distance next */
t = c->sub.code.need;
NEEDBITS(t)
j = c->sub.code.tree + ((uInt)b & (uInt)inflate_mask[t]);
DUMPBITS(j->bits)
e = (uInt)(j->exop);
if (e & 16) /* distance */
{
c->sub.copy.get = e & 15;
c->sub.copy.dist = j->base;
c->mode = DISTEXT;
break;
}
if ((e & 64) == 0) /* next table */
{
c->sub.code.need = e;
c->sub.code.tree = j + j->base;
break;
}
goto badcode;
// c->mode = BADCODE; /* invalid code */
// r = Z_DATA_ERROR;
// LEAVE
case DISTEXT: /* i: getting distance extra */
t = c->sub.copy.get;
NEEDBITS(t)
c->sub.copy.dist += (uInt)b & (uInt)inflate_mask[t];
DUMPBITS(t)
c->mode = COPY;
case COPY: /* o: copying bytes in window, waiting for space */
f = (uInt)(q - s->window) < c->sub.copy.dist ?
s->end - (c->sub.copy.dist - (q - s->window)) :
q - c->sub.copy.dist;
while (c->len)
{
NEEDOUT
OUTBYTE(*f++)
if (f == s->end)
f = s->window;
c->len--;
}
c->mode = START;
break;
case LIT: /* o: got literal, waiting for output space */
NEEDOUT
OUTBYTE(c->sub.lit)
c->mode = START;
break;
case WASH: /* o: got eob, possibly more output */
if (k > 7) /* return unused byte, if any */
{
k -= 8;
n++;
p--; /* can always return one */
}
FLUSH
if (s->read != s->write)
{
r = inflate_flush(z,r);
done = 1;
break;
}
c->mode = END;
case END:
r = inflate_flush(z,Z_STREAM_END);
done = 1;
break;
default:
badcode:
r = inflate_flush(z,Z_STREAM_ERROR);
done = 1;
break;
}
UPDATE
}
if (r != Z_STREAM_END)
return inflate_flush(z, r);
r = Z_OK;
LOAD