From f5f296445fc1feb446b7e4ffce28d577cdebb7c9 Mon Sep 17 00:00:00 2001
From: Masaru Tsuchiyama
Date: Tue, 2 Jun 2026 16:27:29 +0900
Subject: [PATCH 01/17] =?UTF-8?q?GetTickCount()=E3=82=92GetTickCount64()?=
=?UTF-8?q?=E3=81=AB=E7=BD=AE=E3=81=8D=E6=8F=9B=E3=81=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
49日でオーバーフローするGetTickCount()をGetTickCount64()に置き換え。
関連する変数の型をDWORDからULONGLONGに変更し、CheckTimeout()の
DWORDオーバーフロー対策コードを削除して簡略化。
Co-Authored-By: Claude Sonnet 4.6
---
TTProxy/ProxyWSockHook.h | 10 ++++----
teraterm/common/compat_win.cpp | 2 +-
teraterm/common/dlglib.c | 17 ++++++------
teraterm/common/dlglib.h | 2 +-
teraterm/common/ttlib.c | 14 +++++-----
teraterm/common/ttlib.h | 2 +-
teraterm/common/tttypes.h | 2 +-
teraterm/teraterm/buffer.c | 8 +++---
teraterm/teraterm/commlib.c | 2 +-
teraterm/teraterm/filesys.cpp | 4 +--
teraterm/teraterm/filesys_log.cpp | 4 +--
teraterm/teraterm/filesys_proto.cpp | 2 +-
teraterm/teraterm/filesys_proto.h | 2 +-
teraterm/teraterm/ftdlg.cpp | 16 ++++++------
teraterm/teraterm/ftdlg.h | 2 +-
teraterm/teraterm/ftdlg_lite.cpp | 14 +++++-----
teraterm/teraterm/sendmem.cpp | 6 ++---
teraterm/teraterm/teraterm.cpp | 6 ++---
teraterm/teraterm/vtterm.c | 14 +++++-----
teraterm/teraterm/vtwin.cpp | 2 +-
teraterm/teraterm/vtwin.h | 2 +-
teraterm/ttpfile/bplus.c | 6 ++---
teraterm/ttpfile/kermit.c | 8 +++---
teraterm/ttpfile/quickvan.c | 8 +++---
teraterm/ttpfile/raw.c | 10 ++++----
teraterm/ttpfile/xmodem.c | 4 +--
teraterm/ttpfile/ymodem.c | 6 ++---
teraterm/ttpfile/zmodem.c | 10 ++++----
teraterm/ttpmacro/ttl.cpp | 40 +++++++++++------------------
teraterm/ttpmacro/ttmenc.c | 2 +-
ttssh2/ttxssh/ssh.c | 20 +++++++--------
ttssh2/ttxssh/ssh.h | 6 ++---
ttssh2/ttxssh/ttxssh.c | 2 +-
33 files changed, 123 insertions(+), 132 deletions(-)
diff --git a/TTProxy/ProxyWSockHook.h b/TTProxy/ProxyWSockHook.h
index a571a641e..be2725d51 100644
--- a/TTProxy/ProxyWSockHook.h
+++ b/TTProxy/ProxyWSockHook.h
@@ -471,7 +471,7 @@ class ProxyWSockHook {
in_addr addr;
struct in6_addr addr6;
char* buffer;
- DWORD time;
+ ULONGLONG time;
ConnectionInfo(ProxyInfo& proxy, String realhost):proxy(proxy), realhost(realhost), buffer(NULL) {
}
~ConnectionInfo() {
@@ -664,7 +664,7 @@ class ProxyWSockHook {
ConnectionInfo* info = table.get(url);
::LeaveCriticalSection(§ion);
if (info != NULL) {
- info->time = ::GetTickCount();
+ info->time = ::GetTickCount64();
return info;
}
ProxyInfo proxy;
@@ -688,8 +688,8 @@ class ProxyWSockHook {
}
}
if (i >= countof(list)) {
- DWORD now = ::GetTickCount();
- DWORD max = 0;
+ ULONGLONG now = ::GetTickCount64();
+ ULONGLONG max = 0;
int index = -1;
for (i = 0; i < countof(list); i++) {
if (list[i] != NULL) {
@@ -709,7 +709,7 @@ class ProxyWSockHook {
info->addr6.s6_addr[11] = 0xff;
info->addr6.s6_addr[15] = i + 1;
- info->time = ::GetTickCount();
+ info->time = ::GetTickCount64();
return info;
}
};
diff --git a/teraterm/common/compat_win.cpp b/teraterm/common/compat_win.cpp
index 50697632c..5dee78c74 100644
--- a/teraterm/common/compat_win.cpp
+++ b/teraterm/common/compat_win.cpp
@@ -239,7 +239,7 @@ static HWND WINAPI GetConsoleWindowLocal(void)
}
// Format a "unique" NewWindowTitle.
- wsprintfA(pszNewWindowTitle, "%d/%d", GetTickCount(), GetCurrentProcessId());
+ wsprintfA(pszNewWindowTitle, "%I64u/%d", GetTickCount64(), GetCurrentProcessId());
// Change current window title.
SetConsoleTitleA(pszNewWindowTitle);
diff --git a/teraterm/common/dlglib.c b/teraterm/common/dlglib.c
index 25e515aec..164f46e90 100644
--- a/teraterm/common/dlglib.c
+++ b/teraterm/common/dlglib.c
@@ -153,13 +153,14 @@ void SetDlgPercent(HWND HDlg, int id_Item, int id_Progress, LONG a, LONG b, int
}
}
-void SetDlgTime(HWND HDlg, int id_Item, DWORD stime, int bytes)
+void SetDlgTime(HWND HDlg, int id_Item, ULONGLONG stime, int bytes)
{
- static int prev_elapsed;
- int elapsed, rate;
+ static ULONGLONG prev_elapsed;
+ ULONGLONG elapsed;
+ int rate;
wchar_t buff[64];
- elapsed = (GetTickCount() - stime) / 1000;
+ elapsed = (GetTickCount64() - stime) / 1000;
if (elapsed == 0) {
prev_elapsed = 0;
@@ -172,15 +173,15 @@ void SetDlgTime(HWND HDlg, int id_Item, DWORD stime, int bytes)
}
prev_elapsed = elapsed;
- rate = bytes / elapsed;
+ rate = (int)(bytes / elapsed);
if (rate < 1200) {
- _snwprintf_s(buff, _countof(buff), _TRUNCATE, L"%d:%02d (%dBytes/s)", elapsed / 60, elapsed % 60, rate);
+ _snwprintf_s(buff, _countof(buff), _TRUNCATE, L"%llu:%02llu (%dBytes/s)", elapsed / 60, elapsed % 60, rate);
}
else if (rate < 1200000) {
- _snwprintf_s(buff, _countof(buff), _TRUNCATE, L"%d:%02d (%d.%02dKB/s)", elapsed / 60, elapsed % 60, rate / 1000, rate / 10 % 100);
+ _snwprintf_s(buff, _countof(buff), _TRUNCATE, L"%llu:%02llu (%d.%02dKB/s)", elapsed / 60, elapsed % 60, rate / 1000, rate / 10 % 100);
}
else {
- _snwprintf_s(buff, _countof(buff), _TRUNCATE, L"%d:%02d (%d.%02dMB/s)", elapsed / 60, elapsed % 60, rate / (1000 * 1000), rate / 10000 % 100);
+ _snwprintf_s(buff, _countof(buff), _TRUNCATE, L"%llu:%02llu (%d.%02dMB/s)", elapsed / 60, elapsed % 60, rate / (1000 * 1000), rate / 10000 % 100);
}
SetDlgItemTextW(HDlg, id_Item, buff);
diff --git a/teraterm/common/dlglib.h b/teraterm/common/dlglib.h
index ad5989da4..66c82bf60 100644
--- a/teraterm/common/dlglib.h
+++ b/teraterm/common/dlglib.h
@@ -44,7 +44,7 @@ void SetRB(HWND HDlg, int R, int FirstId, int LastId);
void GetRB(HWND HDlg, LPWORD R, int FirstId, int LastId);
void SetDlgNum(HWND HDlg, int id_Item, LONG Num);
void SetDlgPercent(HWND HDlg, int id_Item, int id_Progress, LONG a, LONG b, int *prog);
-void SetDlgTime(HWND HDlg, int id_Item, DWORD elapsed, int bytes);
+void SetDlgTime(HWND HDlg, int id_Item, ULONGLONG elapsed, int bytes);
void SetDropDownList(HWND HDlg, int Id_Item, const char *List[], int nsel);
void SetDropDownListW(HWND HDlg, int Id_Item, const wchar_t *List[], int nsel);
LONG GetCurSel(HWND HDlg, int Id_Item);
diff --git a/teraterm/common/ttlib.c b/teraterm/common/ttlib.c
index 12d865a08..dab3e45c4 100644
--- a/teraterm/common/ttlib.c
+++ b/teraterm/common/ttlib.c
@@ -956,24 +956,24 @@ char *mctimelocal(const char *format, BOOL utc_flag)
* @return 経過時間の文字列
* 不要になったらfree()すること
*/
-char *strelapsed(DWORD start_time)
+char *strelapsed(ULONGLONG start_time)
{
size_t sizeof_strtime = 20;
char *strtime = malloc(sizeof_strtime);
int days, hours, minutes, seconds, msecs;
- DWORD delta = GetTickCount() - start_time;
+ ULONGLONG delta = GetTickCount64() - start_time;
- msecs = delta % 1000;
+ msecs = (int)(delta % 1000);
delta /= 1000;
- seconds = delta % 60;
+ seconds = (int)(delta % 60);
delta /= 60;
- minutes = delta % 60;
+ minutes = (int)(delta % 60);
delta /= 60;
- hours = delta % 24;
- days = delta / 24;
+ hours = (int)(delta % 24);
+ days = (int)(delta / 24);
_snprintf_s(strtime, sizeof_strtime, _TRUNCATE,
"%d %02d:%02d:%02d.%03d",
diff --git a/teraterm/common/ttlib.h b/teraterm/common/ttlib.h
index 498cc4823..13492cb0e 100644
--- a/teraterm/common/ttlib.h
+++ b/teraterm/common/ttlib.h
@@ -137,7 +137,7 @@ DllExport BOOL HasMultiMonitorSupport();
DllExport BOOL HasDnsQuery();
DllExport BOOL HasBalloonTipSupport();
DllExport char *mctimelocal(const char *format, BOOL utc_flag);
-char *strelapsed(DWORD start_time);
+char *strelapsed(ULONGLONG start_time);
void b64encode(PCHAR dst, int dsize, PCHAR src, int len);
DllExport int b64decode(PCHAR dst, int dsize, PCHAR src);
diff --git a/teraterm/common/tttypes.h b/teraterm/common/tttypes.h
index 530f76778..1c9394787 100644
--- a/teraterm/common/tttypes.h
+++ b/teraterm/common/tttypes.h
@@ -869,7 +869,7 @@ typedef struct {
void *NotifyIcon;
- DWORD ConnectedTime;
+ ULONGLONG ConnectedTime;
void (*Log1Byte)(BYTE b);
void (*Log1Bin)(BYTE b);
diff --git a/teraterm/teraterm/buffer.c b/teraterm/teraterm/buffer.c
index 4a196fc26..71ce82cca 100644
--- a/teraterm/teraterm/buffer.c
+++ b/teraterm/teraterm/buffer.c
@@ -115,7 +115,7 @@ static BOOL BoxSelect; // TRUE=矩形選択 / FALSE=行選択
static POINT ClickCell; // クリックした文字cell
static POINT SelectStartOld; // 描画した選択領域、start
static POINT SelectEndOld; // 描画した選択領域、end
-static DWORD SelectStartTime;
+static ULONGLONG SelectStartTime;
static POINT DblClkStart;
static POINT DblClkEnd;
@@ -4749,7 +4749,7 @@ void BuffStartSelect(int Xw, int Yw, BOOL Box, BOOL Shift)
Selected = FALSE;
// 選択開始ガード
- SelectStartTime = GetTickCount();
+ SelectStartTime = GetTickCount64();
Selecting = FALSE;
// push位置
@@ -4778,7 +4778,7 @@ void BuffChangeSelect(int Xw, int Yw, int NClick)
if (!Selecting) {
// 選択ガード?
- if (GetTickCount() - SelectStartTime < ts.SelectStartDelay) {
+ if (GetTickCount64() - SelectStartTime < ts.SelectStartDelay) {
// ガード中
return;
}
@@ -4889,7 +4889,7 @@ void BuffEndSelect(int Xw, int Yw)
(void)Xw;
(void)Yw;
if (!Selecting) {
- if (GetTickCount() - SelectStartTime < ts.SelectStartDelay) {
+ if (GetTickCount64() - SelectStartTime < ts.SelectStartDelay) {
// ガード時間以内なら
// 選択領域解除
SelectEnd = SelectStart;
diff --git a/teraterm/teraterm/commlib.c b/teraterm/teraterm/commlib.c
index 7a9942ddf..92c5125ff 100644
--- a/teraterm/teraterm/commlib.c
+++ b/teraterm/teraterm/commlib.c
@@ -805,7 +805,7 @@ void CommStart(PComVar cv, LONG lParam, PTTSet ts)
break;
}
cv->Ready = TRUE;
- cv->ConnectedTime = GetTickCount();
+ cv->ConnectedTime = GetTickCount64();
}
BOOL CommCanClose(PComVar cv)
diff --git a/teraterm/teraterm/filesys.cpp b/teraterm/teraterm/filesys.cpp
index 70472fc85..cdcfc59aa 100644
--- a/teraterm/teraterm/filesys.cpp
+++ b/teraterm/teraterm/filesys.cpp
@@ -66,7 +66,7 @@ typedef struct {
LONG FileSize; // uint64_t FileSize; TODO
LONG ByteCount; // uint64_t ByteCount;
- DWORD StartTime;
+ ULONGLONG StartTime;
BOOL FilePause;
BOOL FileRetrySend, FileRetryEcho, FileCRSend, FileReadEOF, BinaryMode;
@@ -118,7 +118,7 @@ static BOOL OpenFTDlg(PFileVar fv)
free(DlgCaption);
fv->FilePause = FALSE;
- fv->StartTime = GetTickCount();
+ fv->StartTime = GetTickCount64();
fv->SendDlg = FTDlg; /* File send */
return TRUE;
diff --git a/teraterm/teraterm/filesys_log.cpp b/teraterm/teraterm/filesys_log.cpp
index 26eb3ddf6..70e7ca54d 100644
--- a/teraterm/teraterm/filesys_log.cpp
+++ b/teraterm/teraterm/filesys_log.cpp
@@ -69,7 +69,7 @@ typedef struct {
LONG FileSize; // ? 使っていない
LONG ByteCount; // ファイルサイズ
- DWORD StartTime;
+ ULONGLONG StartTime;
enum enumLineEnd eLineEnd;
@@ -406,7 +406,7 @@ static BOOL LogStart(PFileVar fv, const wchar_t *fname)
}
fv->IsPause = FALSE;
- fv->StartTime = GetTickCount();
+ fv->StartTime = GetTickCount64();
if (ts.DeferredLogWriteMode) {
StartThread(fv);
diff --git a/teraterm/teraterm/filesys_proto.cpp b/teraterm/teraterm/filesys_proto.cpp
index ec9ce6b77..dd36acc20 100644
--- a/teraterm/teraterm/filesys_proto.cpp
+++ b/teraterm/teraterm/filesys_proto.cpp
@@ -92,7 +92,7 @@ static PFileVarProto FileVar = NULL;
static PProtoDlg PtDlg = NULL;
static BOOL cv_ProtoFlag = FALSE;
-static void _SetDlgTime(TFileVarProto *fv, DWORD elapsed, int bytes)
+static void _SetDlgTime(TFileVarProto *fv, ULONGLONG elapsed, int bytes)
{
SetDlgTime(fv->HWin, IDC_PROTOELAPSEDTIME, elapsed, bytes);
}
diff --git a/teraterm/teraterm/filesys_proto.h b/teraterm/teraterm/filesys_proto.h
index 0936ec6ec..8933d3ff7 100644
--- a/teraterm/teraterm/filesys_proto.h
+++ b/teraterm/teraterm/filesys_proto.h
@@ -153,7 +153,7 @@ typedef TFileVarProto *PFileVarProto;
// UIなど情報表示用関数
typedef struct InfoOp_ {
void (*InitDlgProgress)(struct FileVarProto *fv, int *CurProgStat);
- void (*SetDlgTime)(struct FileVarProto *fv, DWORD elapsed, int bytes);
+ void (*SetDlgTime)(struct FileVarProto *fv, ULONGLONG elapsed, int bytes);
void (*SetDlgPacketNum)(struct FileVarProto *fv, LONG Num);
void (*SetDlgByteCount)(struct FileVarProto *fv, LONG Num);
void (*SetDlgPercent)(struct FileVarProto *fv, LONG a, LONG b, int *p);
diff --git a/teraterm/teraterm/ftdlg.cpp b/teraterm/teraterm/ftdlg.cpp
index 66009075c..214d93250 100644
--- a/teraterm/teraterm/ftdlg.cpp
+++ b/teraterm/teraterm/ftdlg.cpp
@@ -151,13 +151,13 @@ void CFileTransDlg::ChangeButton(BOOL PauseFlag)
}
}
-void CFileTransDlg::RefreshNum(DWORD StartTime, LONG FileSize, LONG ByteCount)
+void CFileTransDlg::RefreshNum(ULONGLONG StartTime, LONG FileSize, LONG ByteCount)
{
char NumStr[24];
double rate;
int rate2;
- static DWORD prev_elapsed;
- DWORD elapsed;
+ static ULONGLONG prev_elapsed;
+ ULONGLONG elapsed;
if (OpId == OpSendFile) {
if (StartTime == 0) {
@@ -165,17 +165,17 @@ void CFileTransDlg::RefreshNum(DWORD StartTime, LONG FileSize, LONG ByteCount)
prev_elapsed = 0;
}
else {
- elapsed = (GetTickCount() - StartTime) / 1000;
+ elapsed = (GetTickCount64() - StartTime) / 1000;
if (elapsed != prev_elapsed && elapsed != 0) {
- rate2 = ByteCount / elapsed;
+ rate2 = (int)(ByteCount / elapsed);
if (rate2 < 1200) {
- _snprintf_s(NumStr, sizeof(NumStr), _TRUNCATE, "%d:%02d (%dBytes/s)", elapsed / 60, elapsed % 60, rate2);
+ _snprintf_s(NumStr, sizeof(NumStr), _TRUNCATE, "%llu:%02llu (%dBytes/s)", elapsed / 60, elapsed % 60, rate2);
}
else if (rate2 < 1200000) {
- _snprintf_s(NumStr, sizeof(NumStr), _TRUNCATE, "%d:%02d (%d.%02dKB/s)", elapsed / 60, elapsed % 60, rate2 / 1000, rate2 / 10 % 100);
+ _snprintf_s(NumStr, sizeof(NumStr), _TRUNCATE, "%llu:%02llu (%d.%02dKB/s)", elapsed / 60, elapsed % 60, rate2 / 1000, rate2 / 10 % 100);
}
else {
- _snprintf_s(NumStr, sizeof(NumStr), _TRUNCATE, "%d:%02d (%d.%02dMB/s)", elapsed / 60, elapsed % 60, rate2 / (1000*1000), rate2 / 10000 % 100);
+ _snprintf_s(NumStr, sizeof(NumStr), _TRUNCATE, "%llu:%02llu (%d.%02dMB/s)", elapsed / 60, elapsed % 60, rate2 / (1000*1000), rate2 / 10000 % 100);
}
SetDlgItemText(IDC_TRANS_ETIME, NumStr);
prev_elapsed = elapsed;
diff --git a/teraterm/teraterm/ftdlg.h b/teraterm/teraterm/ftdlg.h
index 5283598c4..6d3e83444 100644
--- a/teraterm/teraterm/ftdlg.h
+++ b/teraterm/teraterm/ftdlg.h
@@ -57,7 +57,7 @@ class CFileTransDlg : public TTCDialog
BOOL Create(HINSTANCE hInstance, Info *info);
void ChangeButton(BOOL PauseFlag);
- void RefreshNum(DWORD StartTime, LONG FileSize, LONG ByteCount);
+ void RefreshNum(ULONGLONG StartTime, LONG FileSize, LONG ByteCount);
private:
virtual BOOL OnCancel();
diff --git a/teraterm/teraterm/ftdlg_lite.cpp b/teraterm/teraterm/ftdlg_lite.cpp
index 44558e98e..1461ef283 100644
--- a/teraterm/teraterm/ftdlg_lite.cpp
+++ b/teraterm/teraterm/ftdlg_lite.cpp
@@ -174,8 +174,8 @@ class PrivateData : public TTCDialog
BOOL Pause;
BOOL check_2sec;
BOOL show;
- DWORD prev_elapsed;
- DWORD StartTime;
+ ULONGLONG prev_elapsed;
+ ULONGLONG StartTime;
BOOL HideDialog;
CFileTransLiteDlg::Observer *observer_;
@@ -215,7 +215,7 @@ BOOL CFileTransLiteDlg::Create(HINSTANCE hInstance, HWND hParent, const wchar_t
}
pData->SetDlgItemTextA(IDC_TRANS_ETIME, "0:00");
- pData->StartTime = GetTickCount();
+ pData->StartTime = GetTickCount64();
pData->prev_elapsed = 0;
return Ok;
@@ -232,10 +232,10 @@ void CFileTransLiteDlg::RefreshNum(size_t ByteCount, size_t FileSize)
return;
}
- const DWORD now = GetTickCount();
+ const ULONGLONG now = GetTickCount64();
if (!pData->check_2sec) {
- DWORD elapsed_ms = now - pData->StartTime;
+ ULONGLONG elapsed_ms = now - pData->StartTime;
if (elapsed_ms > 2 * 1000) {
// 2sec経過
pData->check_2sec = TRUE;
@@ -247,10 +247,10 @@ void CFileTransLiteDlg::RefreshNum(size_t ByteCount, size_t FileSize)
}
char NumStr[24];
- DWORD elapsed = (now - pData->StartTime) / 1000;
+ ULONGLONG elapsed = (now - pData->StartTime) / 1000;
if (elapsed != pData->prev_elapsed && elapsed != 0) {
char elapsed_str[24];
- _snprintf_s(elapsed_str, sizeof(elapsed_str), _TRUNCATE, "%ld:%02ld",
+ _snprintf_s(elapsed_str, sizeof(elapsed_str), _TRUNCATE, "%llu:%02llu",
elapsed / 60, elapsed % 60);
char speed_str[24];
diff --git a/teraterm/teraterm/sendmem.cpp b/teraterm/teraterm/sendmem.cpp
index 615299de2..465b609f5 100644
--- a/teraterm/teraterm/sendmem.cpp
+++ b/teraterm/teraterm/sendmem.cpp
@@ -82,7 +82,7 @@ typedef struct SendMemTag {
size_t send_left;
size_t send_index;
BOOL waited;
- DWORD last_send_tick;
+ ULONGLONG last_send_tick;
//
CFileTransLiteDlg *dlg;
class SendMemDlgObserver *dlg_observer;
@@ -377,7 +377,7 @@ void SendMemContinuously(void)
}
if (p->waited) {
- if (GetTickCount() - p->last_send_tick < p->delay_tick) {
+ if (GetTickCount64() - p->last_send_tick < p->delay_tick) {
// ウエイトする
return;
}
@@ -518,7 +518,7 @@ void SendMemContinuously(void)
if (p->send_left != 0 && need_delay) {
// waitに入る
p->waited = TRUE;
- p->last_send_tick = GetTickCount();
+ p->last_send_tick = GetTickCount64();
// タイマーはidleを動作させるために使用している
SetTimer(p->hWnd, p->timer_id, p->delay_tick, NULL);
}
diff --git a/teraterm/teraterm/teraterm.cpp b/teraterm/teraterm/teraterm.cpp
index 49c118b0a..902af9ff3 100644
--- a/teraterm/teraterm/teraterm.cpp
+++ b/teraterm/teraterm/teraterm.cpp
@@ -398,7 +398,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst,
MSG msg;
for (;;) {
// idle状態でメッセージがない場合
- DWORD idle_enter_tick = GetTickCount();
+ ULONGLONG idle_enter_tick = GetTickCount64();
BOOL sleep_enable = FALSE;
for (;;) {
// idle処理を行う
@@ -412,7 +412,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst,
if (!continue_idle) {
// FALSEが戻ってきたらidle処理は不要
if (!sleep_enable) {
- if (GetTickCount() - idle_enter_tick > 20) {
+ if (GetTickCount64() - idle_enter_tick > 20) {
// 20ms以上idle処理不要だったらSleep()を入れる
sleep_enable = TRUE;
}
@@ -423,7 +423,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst,
lCount = 0;
}
else {
- idle_enter_tick = GetTickCount();
+ idle_enter_tick = GetTickCount64();
sleep_enable = FALSE;
}
diff --git a/teraterm/teraterm/vtterm.c b/teraterm/teraterm/vtterm.c
index bb1a8722e..dd41bd93f 100644
--- a/teraterm/teraterm/vtterm.c
+++ b/teraterm/teraterm/vtterm.c
@@ -196,8 +196,8 @@ static int FilterTop, FilterBottom, FilterLeft, FilterRight;
static BOOL SavedIMEstatus;
/* Beep over-used */
-static DWORD BeepStartTime = 0;
-static DWORD BeepSuppressTime = 0;
+static ULONGLONG BeepStartTime = 0;
+static ULONGLONG BeepSuppressTime = 0;
static DWORD BeepOverUsedCount = 0;
static _locale_t CLocale = NULL;
@@ -345,7 +345,7 @@ void ResetTerminal() /*reset variables but don't update screen */
LastPutCharacter = 0;
// Beep over-used
- BeepStartTime = GetTickCount();
+ BeepStartTime = GetTickCount64();
BeepSuppressTime = BeepStartTime - ts.BeepSuppressTime * 1000;
BeepStartTime -= (ts.BeepOverUsedTime * 1000);
BeepOverUsedCount = ts.BeepOverUsedCount;
@@ -5398,8 +5398,8 @@ int VTParse()
while ((c>0) && (ChangeEmu==0)) {
#if defined(DEBUG_DUMP_INPUTCODE)
{
- static DWORD prev_tick;
- DWORD now = GetTickCount();
+ static ULONGLONG prev_tick;
+ ULONGLONG now = GetTickCount64();
if (prev_tick == 0) prev_tick = now;
if (now - prev_tick > 1*1000) {
printf("\n");
@@ -5777,9 +5777,9 @@ static void VisualBell(void)
static void RingBell(int type)
{
- DWORD now;
+ ULONGLONG now;
- now = GetTickCount();
+ now = GetTickCount64();
if (now - BeepSuppressTime < ts.BeepSuppressTime * 1000) {
BeepSuppressTime = now;
}
diff --git a/teraterm/teraterm/vtwin.cpp b/teraterm/teraterm/vtwin.cpp
index 00e7586cf..74722f60d 100644
--- a/teraterm/teraterm/vtwin.cpp
+++ b/teraterm/teraterm/vtwin.cpp
@@ -2207,7 +2207,7 @@ void CVTWindow::OnKeyDown(WPARAM nChar, UINT nRepCnt, UINT nFlags)
#if UNICODE_DEBUG
if (UnicodeDebugParam.CodePopupEnable)
{
- const DWORD now = GetTickCount();
+ const ULONGLONG now = GetTickCount64();
switch(CtrlKeyState) {
case 0:
if (nChar == UnicodeDebugParam.CodePopupKey1) {
diff --git a/teraterm/teraterm/vtwin.h b/teraterm/teraterm/vtwin.h
index 05a5ee442..70a928df5 100644
--- a/teraterm/teraterm/vtwin.h
+++ b/teraterm/teraterm/vtwin.h
@@ -72,7 +72,7 @@ class CVTWindow : public TTCFrameWnd
#if UNICODE_DEBUG
TipWin *TipWinCodeDebug;
int CtrlKeyState; // 0:開始/1:押す/2:離す/3:押す(表示状態)
- DWORD CtrlKeyDownTick; // 最初に押したtick
+ ULONGLONG CtrlKeyDownTick; // 最初に押したtick
#endif
// TipWin
diff --git a/teraterm/ttpfile/bplus.c b/teraterm/ttpfile/bplus.c
index f85866fda..c63f1e3ef 100644
--- a/teraterm/ttpfile/bplus.c
+++ b/teraterm/ttpfile/bplus.c
@@ -80,7 +80,7 @@ typedef struct {
int ProgStat;
- DWORD StartTime;
+ ULONGLONG StartTime;
DWORD FileMtime;
@@ -162,7 +162,7 @@ static BOOL BPInit(TProto *pv, PComVar cv, PTTSet ts)
fv->InfoOp->SetDlgProtoText(fv, "B-Plus");
fv->InfoOp->InitDlgProgress(fv, &bv->ProgStat);
- bv->StartTime = GetTickCount();
+ bv->StartTime = GetTickCount64();
/* file name, file size */
if (bv->BPMode==IdBPSend)
@@ -610,7 +610,7 @@ static BOOL FTCreateFile(PBPVar bv)
if (bv->ProgStat != -1) {
bv->ProgStat = 0;
}
- bv->StartTime = GetTickCount();
+ bv->StartTime = GetTickCount64();
return TRUE;
}
diff --git a/teraterm/ttpfile/kermit.c b/teraterm/ttpfile/kermit.c
index bda13abe4..0b50977e2 100644
--- a/teraterm/ttpfile/kermit.c
+++ b/teraterm/ttpfile/kermit.c
@@ -79,7 +79,7 @@ typedef struct {
int ProgStat;
- DWORD StartTime;
+ ULONGLONG StartTime;
DWORD FileMtime;
@@ -1086,7 +1086,7 @@ static BOOL KmtSendNextFile(PKmtVar kv)
kv->ByteCount = 0;
kv->ProgStat = 0;
- kv->StartTime = GetTickCount();
+ kv->StartTime = GetTickCount64();
fv->InfoOp->SetDlgProtoFileName(fv, kv->FullName);
fv->InfoOp->SetDlgByteCount(fv, kv->ByteCount);
@@ -1191,7 +1191,7 @@ static BOOL KmtInit(TProto *pv, PComVar cv, PTTSet ts)
if (kv->KmtMode == IdKmtSend) {
fv->InfoOp->InitDlgProgress(fv, &kv->ProgStat);
- kv->StartTime = GetTickCount();
+ kv->StartTime = GetTickCount64();
}
else {
kv->ProgStat = -1;
@@ -1347,7 +1347,7 @@ static BOOL FTCreateFile(PKmtVar kv)
if (kv->ProgStat != -1) {
kv->ProgStat = 0;
}
- kv->StartTime = GetTickCount();
+ kv->StartTime = GetTickCount64();
return TRUE;
}
diff --git a/teraterm/ttpfile/quickvan.c b/teraterm/ttpfile/quickvan.c
index 1b23bc9d4..df3ff364c 100644
--- a/teraterm/ttpfile/quickvan.c
+++ b/teraterm/ttpfile/quickvan.c
@@ -65,7 +65,7 @@ typedef struct {
int ProgStat;
- DWORD StartTime;
+ ULONGLONG StartTime;
DWORD FileMtime;
@@ -192,7 +192,7 @@ static BOOL QVInit(TProto *pv, PComVar cv, PTTSet ts)
fv->InfoOp->SetDlgProtoText(fv, "Quick-VAN");
fv->InfoOp->InitDlgProgress(fv, &qv->ProgStat);
- qv->StartTime = GetTickCount();
+ qv->StartTime = GetTickCount64();
qv->SeqNum = 0;
qv->FileNum = 0;
@@ -470,7 +470,7 @@ static BOOL FTCreateFile(PQVVar qv)
if (qv->ProgStat != -1) {
qv->ProgStat = 0;
}
- qv->StartTime = GetTickCount();
+ qv->StartTime = GetTickCount64();
return TRUE;
}
@@ -930,7 +930,7 @@ static void QVSendVFILE(PQVVar qv)
/* file no. */
qv->FileNum++;
qv->ProgStat = 0;
- qv->StartTime = GetTickCount();
+ qv->StartTime = GetTickCount64();
i = 3;
QVPutNum2(qv,qv->FileNum,&i);
/* file name */
diff --git a/teraterm/ttpfile/raw.c b/teraterm/ttpfile/raw.c
index 4617703c6..e55c05a82 100644
--- a/teraterm/ttpfile/raw.c
+++ b/teraterm/ttpfile/raw.c
@@ -38,7 +38,7 @@ typedef struct {
const char *FullName; // Windows上のファイル名 UTF-8
BOOL FileOpen;
LONG ByteCount;
- DWORD StartTime;
+ ULONGLONG StartTime;
PComVar cv;
enum {
STATE_FLUSH, // 処理開始時に受信データを捨てる
@@ -148,12 +148,12 @@ static BOOL RawReadPacket(void *arg)
PComVar cv = rv->cv;
BYTE Buff[InBuffSize];
int BuffCount;
- static DWORD prev_elapsed;
- DWORD elapsed;
+ static ULONGLONG prev_elapsed;
+ ULONGLONG elapsed;
if (cv->InBuffCount > 0) {
if (rv->StartTime == 0) {
- rv->StartTime = GetTickCount();
+ rv->StartTime = GetTickCount64();
prev_elapsed = rv->StartTime;
fv->InfoOp->SetDlgPacketNum(fv, 1);
}
@@ -166,7 +166,7 @@ static BOOL RawReadPacket(void *arg)
LeaveCriticalSection(&cv->InBuff_lock);
file->WriteFile(file, Buff, BuffCount);
rv->ByteCount += BuffCount;
- elapsed = (GetTickCount() - prev_elapsed) / 250;
+ elapsed = (GetTickCount64() - prev_elapsed) / 250;
if (elapsed != prev_elapsed) {
prev_elapsed = elapsed;
fv->InfoOp->SetDlgByteCount(fv, rv->ByteCount);
diff --git a/teraterm/ttpfile/xmodem.c b/teraterm/ttpfile/xmodem.c
index 3c9ebddbb..4d9d2d4f5 100644
--- a/teraterm/ttpfile/xmodem.c
+++ b/teraterm/ttpfile/xmodem.c
@@ -80,7 +80,7 @@ typedef struct {
int ProgStat;
- DWORD StartTime;
+ ULONGLONG StartTime;
DWORD FileMtime;
@@ -299,7 +299,7 @@ static BOOL XInit(TProto *pv, PComVar cv, PTTSet ts)
xv->ProgStat = -1;
}
fv->InfoOp->SetDlgProtoFileName(fv, xv->FullName);
- xv->StartTime = GetTickCount();
+ xv->StartTime = GetTickCount64();
xv->PktNumOffset = 0;
xv->PktNum = 0;
diff --git a/teraterm/ttpfile/ymodem.c b/teraterm/ttpfile/ymodem.c
index 013c53981..4cd412e8f 100644
--- a/teraterm/ttpfile/ymodem.c
+++ b/teraterm/ttpfile/ymodem.c
@@ -72,7 +72,7 @@ typedef struct {
int ProgStat;
- DWORD StartTime;
+ ULONGLONG StartTime;
DWORD FileMtime;
@@ -341,7 +341,7 @@ static void initialize_file_info(PYVar yv)
} else {
yv->ProgStat = -1;
}
- yv->StartTime = GetTickCount();
+ yv->StartTime = GetTickCount64();
fv->InfoOp->SetDlgProtoFileName(fv, yv->FullName);
yv->PktNumOffset = 0;
@@ -501,7 +501,7 @@ static BOOL FTCreateFile(PYVar yv)
if (yv->ProgStat != -1) {
yv->ProgStat = 0;
}
- yv->StartTime = GetTickCount();
+ yv->StartTime = GetTickCount64();
return TRUE;
}
diff --git a/teraterm/ttpfile/zmodem.c b/teraterm/ttpfile/zmodem.c
index 28d802a16..fb587b778 100644
--- a/teraterm/ttpfile/zmodem.c
+++ b/teraterm/ttpfile/zmodem.c
@@ -116,7 +116,7 @@ typedef struct {
int ProgStat;
- DWORD StartTime;
+ ULONGLONG StartTime;
DWORD FileMtime;
@@ -640,7 +640,7 @@ static void ZSendFileDat(PZVar zv)
zv->ByteCount = 0;
zv->ProgStat = 0;
- zv->StartTime = GetTickCount();
+ zv->StartTime = GetTickCount64();
fv->InfoOp->SetDlgByteCount(fv, zv->ByteCount);
fv->InfoOp->SetDlgPercent(fv, zv->ByteCount, zv->FileSize, &zv->ProgStat);
fv->InfoOp->SetDlgTime(fv, zv->StartTime, zv->ByteCount);
@@ -746,7 +746,7 @@ static BOOL ZInit(TProto *pv, PComVar cv, PTTSet ts)
fv->InfoOp->SetDlgProtoText(fv, "ZMODEM");
fv->InfoOp->InitDlgProgress(fv, &zv->ProgStat);
- zv->StartTime = GetTickCount();
+ zv->StartTime = GetTickCount64();
zv->FileSize = 0;
zv->FileMtime = 0;
@@ -1107,7 +1107,7 @@ static BOOL FTCreateFile(PZVar zv)
if (zv->ProgStat != -1) {
zv->ProgStat = 0;
}
- zv->StartTime = GetTickCount();
+ zv->StartTime = GetTickCount64();
return TRUE;
}
@@ -1169,7 +1169,7 @@ static BOOL ZParseFile(PZVar zv)
if (zv->FileSize > 0)
fv->InfoOp->SetDlgPercent(fv,
0, zv->FileSize, &zv->ProgStat);
- fv->InfoOp->SetDlgTime(fv, GetTickCount(), zv->ByteCount);
+ fv->InfoOp->SetDlgTime(fv, GetTickCount64(), zv->ByteCount);
/* set timeout for data */
fv->FTSetTimeOut(fv, zv->TimeOut);
diff --git a/teraterm/ttpmacro/ttl.cpp b/teraterm/ttpmacro/ttl.cpp
index 8c3d6d8fa..ae348ec7d 100644
--- a/teraterm/ttpmacro/ttl.cpp
+++ b/teraterm/ttpmacro/ttl.cpp
@@ -81,7 +81,7 @@ static int EndIfFlag;
static HWND HMainWin;
// Timeout
static DWORD TimeLimit;
-static DWORD TimeStart;
+static ULONGLONG TimeStart;
// for 'WaitEvent' command
static int WakeupCondition;
@@ -1577,7 +1577,7 @@ static WORD TTLFileLock(void)
DWORD timeout;
int result;
BOOL ret;
- DWORD dwStart;
+ ULONGLONG dwStart;
Err = 0;
GetIntVal(&fhi,&Err);
@@ -1592,7 +1592,7 @@ static WORD TTLFileLock(void)
timeout = timeoutI * 1000;
result = 1; // error
- dwStart = GetTickCount();
+ dwStart = GetTickCount64();
do {
ret = LockFile(FH, 0, 0, (DWORD)-1, (DWORD)-1);
if (ret != 0) { // ロック成功
@@ -1600,7 +1600,7 @@ static WORD TTLFileLock(void)
break;
}
Sleep(1);
- } while (GetTickCount() - dwStart < (timeout*1000));
+ } while (GetTickCount64() - dwStart < (timeout*1000));
SetResult(result);
return Err;
@@ -3446,7 +3446,7 @@ static WORD TTLPause(void)
{
TTLStatus = IdTTLPause;
TimeLimit = (DWORD)(TimeOut*1000);
- TimeStart = GetTickCount();
+ TimeStart = GetTickCount64();
SetTimer(HMainWin, IdTimeOutTimer, TIMEOUT_TIMER_MS, NULL);
}
return Err;
@@ -3548,7 +3548,7 @@ static WORD TTLRecvLn(void)
if (TimeOut>0)
{
TimeLimit = (DWORD)TimeOut;
- TimeStart = GetTickCount();
+ TimeStart = GetTickCount64();
SetTimer(HMainWin, IdTimeOutTimer, TIMEOUT_TIMER_MS, NULL);
}
@@ -5469,10 +5469,9 @@ static WORD TTLUptime(void)
Err = ErrSyntax;
if (Err!=0) return Err;
- // Windows OSが起動してからの経過時間(ミリ秒)を取得する。ただし、49日を経過すると、0に戻る。
- // GetTickCount64() API(Vista以降)を使うと、オーバーフローしなくなるが、そもそもTera Termでは
- // 64bit変数をサポートしていないので、意味がない。
- tick = GetTickCount();
+ // Windows OSが起動してからの経過時間(ミリ秒)を取得する。
+ // マクロ変数は32bitのため下位32bitのみ格納する。
+ tick = (DWORD)GetTickCount64();
SetIntVal(VarId, tick);
@@ -5533,7 +5532,7 @@ static WORD TTLWait(BOOL Ln)
if (TimeOut>0)
{
TimeLimit = (DWORD)TimeOut;
- TimeStart = GetTickCount();
+ TimeStart = GetTickCount64();
SetTimer(HMainWin, IdTimeOutTimer, TIMEOUT_TIMER_MS, NULL);
}
}
@@ -5603,7 +5602,7 @@ static WORD TTLWaitEvent(void)
if (TimeOut>0)
{
TimeLimit = (DWORD)TimeOut;
- TimeStart = GetTickCount();
+ TimeStart = GetTickCount64();
SetTimer(HMainWin, IdTimeOutTimer, TIMEOUT_TIMER_MS, NULL);
}
@@ -5645,7 +5644,7 @@ static WORD TTLWaitN(void)
if (TimeOut>0)
{
TimeLimit = (DWORD)TimeOut;
- TimeStart = GetTickCount();
+ TimeStart = GetTickCount64();
SetTimer(HMainWin, IdTimeOutTimer, TIMEOUT_TIMER_MS, NULL);
}
@@ -5685,7 +5684,7 @@ static WORD TTLWaitRecv(void)
if (TimeOut>0)
{
TimeLimit = (DWORD)TimeOut;
- TimeStart = GetTickCount();
+ TimeStart = GetTickCount64();
SetTimer(HMainWin, IdTimeOutTimer, TIMEOUT_TIMER_MS, NULL);
}
return Err;
@@ -6559,17 +6558,8 @@ void SetResult(int ResultCode)
BOOL CheckTimeout()
{
- BOOL ret;
- DWORD TimeUp = (TimeStart+TimeLimit);
-
- if (TimeUp > TimeStart) {
- ret = (GetTickCount() > TimeUp);
- }
- else { // for DWORD overflow (49.7 days)
- DWORD TimeTmp = GetTickCount();
- ret = (TimeUp < TimeTmp && TimeTmp >= TimeStart);
- }
- return ret;
+ ULONGLONG TimeUp = TimeStart + TimeLimit;
+ return (GetTickCount64() > TimeUp);
}
BOOL TestWakeup(int Wakeup)
diff --git a/teraterm/ttpmacro/ttmenc.c b/teraterm/ttpmacro/ttmenc.c
index ff36bcc43..ff524f339 100644
--- a/teraterm/ttpmacro/ttmenc.c
+++ b/teraterm/ttpmacro/ttmenc.c
@@ -90,7 +90,7 @@ void Encrypt(const char *InStr, PCHAR OutStr)
if (InStr[0]==0) {
return;
}
- srand(LOWORD(GetTickCount()));
+ srand((unsigned)GetTickCount64());
r = (BYTE)(rand() & 0x3f);
r2 = (~r) & 0x3f;
OutStr[0] = r;
diff --git a/ttssh2/ttxssh/ssh.c b/ttssh2/ttxssh/ssh.c
index a898e8f38..c8eff7300 100644
--- a/ttssh2/ttxssh/ssh.c
+++ b/ttssh2/ttxssh/ssh.c
@@ -9039,24 +9039,24 @@ static INT_PTR CALLBACK ssh_scp_dlg_thread_proc(HWND hWnd, UINT msg, WPARAM wp,
SendDlgItemMessage(hWnd, IDC_PROGBAR, PBM_SETPOS, (WPARAM)c->scp.ProgStat, 0);
}
- int elapsed = (GetTickCount() - c->scp.stime) / 1000;
+ ULONGLONG elapsed = (GetTickCount64() - c->scp.stime) / 1000;
if (elapsed > c->scp.prev_elapsed) {
if (elapsed > 2) {
rate = (int)(transfered / elapsed);
if (rate < 1200) {
- _snprintf_s(s, sizeof(s), _TRUNCATE, "%d:%02d (%d %s)", elapsed / 60, elapsed % 60, rate, "Bytes/s");
+ _snprintf_s(s, sizeof(s), _TRUNCATE, "%llu:%02llu (%d %s)", elapsed / 60, elapsed % 60, rate, "Bytes/s");
} else if (rate < 1200000) {
- _snprintf_s(s, sizeof(s), _TRUNCATE, "%d:%02d (%d.%02d %s)", elapsed / 60, elapsed % 60, rate / 1000, rate / 10 % 100, "KBytes/s");
+ _snprintf_s(s, sizeof(s), _TRUNCATE, "%llu:%02llu (%d.%02d %s)", elapsed / 60, elapsed % 60, rate / 1000, rate / 10 % 100, "KBytes/s");
} else {
- _snprintf_s(s, sizeof(s), _TRUNCATE, "%d:%02d (%d.%02d %s)", elapsed / 60, elapsed % 60, rate / (1000 * 1000), rate / 10000 % 100, "MBytes/s");
+ _snprintf_s(s, sizeof(s), _TRUNCATE, "%llu:%02llu (%d.%02d %s)", elapsed / 60, elapsed % 60, rate / (1000 * 1000), rate / 10000 % 100, "MBytes/s");
}
} else {
- _snprintf_s(s, sizeof(s), _TRUNCATE, "%d:%02d", elapsed / 60, elapsed % 60);
+ _snprintf_s(s, sizeof(s), _TRUNCATE, "%llu:%02llu", elapsed / 60, elapsed % 60);
}
SendDlgItemMessage(hWnd, IDC_PROGTIME, WM_SETTEXT, 0, (LPARAM)s);
c->scp.prev_elapsed = elapsed;
}
- c->scp.ProcessedTime = GetTickCount();
+ c->scp.ProcessedTime = GetTickCount64();
return FALSE;
case WM_COMMAND:
@@ -9137,7 +9137,7 @@ static unsigned __stdcall ssh_scp_dlg_thread(void *p)
c->scp.prev_elapsed = 0;
c->scp.filesndsize = 0;
c->scp.canceled = FALSE;
- c->scp.stime = GetTickCount();
+ c->scp.stime = GetTickCount64();
c->scp.ProcessedTime = c->scp.stime;
SetWindowLongPtr(hDlgWnd, GWLP_USERDATA, (LONG_PTR)c);
SetTimer(hDlgWnd, c->self_id, SCPDLG_UPDATE_INTERVAL, NULL);
@@ -9174,7 +9174,7 @@ static HANDLE start_ssh_scp_dlg_thread(Channel_t *c)
// スレッド起動待ち
WaitForSingleObject(c->scp.ScpStartThreadEvent, 5000 /*msec*/);
ResetEvent(c->scp.ScpStartThreadEvent);
- c->scp.stime = GetTickCount();
+ c->scp.stime = GetTickCount64();
return thread;
}
@@ -9241,7 +9241,7 @@ static unsigned __stdcall ssh_scp_thread(void *p)
c->scp.filesndsize += ret;
#if 1 // 高負荷対策
// 進捗ダイアログの描画が間に合わない場合は、負荷が下がるまで待つ
- while (GetTickCount() - c->scp.ProcessedTime > SCPDLG_UPDATE_INTERVAL * 3) {
+ while (GetTickCount64() - c->scp.ProcessedTime > SCPDLG_UPDATE_INTERVAL * 3) {
Sleep(20);
if (pvar == NULL || pvar->socket == INVALID_SOCKET || c->scp.state == SCP_CLOSING || c->used == 0) {
goto cancel_abort;
@@ -9405,7 +9405,7 @@ static unsigned __stdcall ssh_scp_receive_thread(void *p)
}
#if 1 // 高負荷対策
// 進捗ダイアログの描画が間に合わない場合は、負荷が下がるまで待つ
- while (GetTickCount() - c->scp.ProcessedTime > SCPDLG_UPDATE_INTERVAL * 3) {
+ while (GetTickCount64() - c->scp.ProcessedTime > SCPDLG_UPDATE_INTERVAL * 3) {
Sleep(20);
if (pvar == NULL || pvar->socket == INVALID_SOCKET || c->scp.state == SCP_CLOSING || c->used == 0) {
goto cancel_abort;
diff --git a/ttssh2/ttxssh/ssh.h b/ttssh2/ttxssh/ssh.h
index cb027b041..adfe594b8 100644
--- a/ttssh2/ttxssh/ssh.h
+++ b/ttssh2/ttxssh/ssh.h
@@ -552,10 +552,10 @@ typedef struct scp {
PTInstVar pvar;
HANDLE ScpStartThreadEvent;
BOOL canceled;
- DWORD stime;
- int prev_elapsed;
+ ULONGLONG stime;
+ ULONGLONG prev_elapsed;
int ProgStat;
- DWORD ProcessedTime;
+ ULONGLONG ProcessedTime;
// for receiving file
long long filetotalsize;
long long filercvsize;
diff --git a/ttssh2/ttxssh/ttxssh.c b/ttssh2/ttxssh/ttxssh.c
index b2f1421ee..867cfa751 100644
--- a/ttssh2/ttxssh/ttxssh.c
+++ b/ttssh2/ttxssh/ttxssh.c
@@ -604,7 +604,7 @@ static unsigned short find_local_port(PTInstVar pvar)
if we're unlucky). They do not need to be (and are not)
cryptographically strong.
*/
- srand((unsigned) GetTickCount());
+ srand((unsigned)GetTickCount64());
for (tries = 20; tries > 0; tries--) {
memset(&hints, 0, sizeof(hints));
From ae75417810c820fc8151fe2e4cdbdc3180537ac8 Mon Sep 17 00:00:00 2001
From: Masaru Tsuchiyama
Date: Thu, 4 Jun 2026 13:25:05 +0900
Subject: [PATCH 02/17] =?UTF-8?q?TTL=E3=83=9E=E3=82=AF=E3=83=AD=E3=81=AB64?=
=?UTF-8?q?=E3=83=93=E3=83=83=E3=83=88=E6=95=B4=E6=95=B0=E5=9E=8B(int64)?=
=?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
`int64 varname` 構文で64ビット整数変数を宣言できるようにし、
`uptime` コマンドがTypInteger64変数に対して64ビット全体を格納するよう対応。
これにより OS 起動から 49.7 日以上経過した環境でも正確な経過時間計測が可能。
- ttmparse.h/cpp: TypInteger64型追加、式評価器をlong longに変更、
NewInt64Var/GetIntVal(int*)オーバーロード追加
- ttl.cpp: TTLInt64Decl追加、TTLUptime 64bit対応、ExecCmndにTypInteger64代入処理追加
- tests/wait_timeout.ttl: int64変数を使った経過時間テストを追加
Co-Authored-By: Claude Sonnet 4.6
---
teraterm/ttpmacro/ttl.cpp | 89 ++++++++++-------
teraterm/ttpmacro/ttmparse.cpp | 172 +++++++++++++++++++++------------
teraterm/ttpmacro/ttmparse.h | 14 ++-
tests/wait_timeout.ttl | 41 ++++++++
4 files changed, 218 insertions(+), 98 deletions(-)
create mode 100644 tests/wait_timeout.ttl
diff --git a/teraterm/ttpmacro/ttl.cpp b/teraterm/ttpmacro/ttl.cpp
index ae348ec7d..d7df2c64a 100644
--- a/teraterm/ttpmacro/ttl.cpp
+++ b/teraterm/ttpmacro/ttl.cpp
@@ -373,7 +373,7 @@ static WORD TTLCommCmdFile(char Cmd, int Wait)
static WORD TTLCommCmdBin(char Cmd, int Wait)
{
- int Val;
+ long long Val;
WORD Err;
Err = 0;
@@ -394,7 +394,7 @@ static WORD TTLCommCmdBin(char Cmd, int Wait)
static WORD TTLCommCmdDeb(void)
{
- int Val;
+ long long Val;
WORD Err;
Err = 0;
@@ -414,7 +414,7 @@ static WORD TTLCommCmdDeb(void)
static WORD TTLCommCmdInt(char Cmd, int Wait)
{
- int Val;
+ long long Val;
char Str[21];
WORD Err;
@@ -910,7 +910,7 @@ static WORD TTLDim(WORD type)
TVariableType VarType;
TName Name;
TVarId VarId;
- int size;
+ long long size;
Err = 0;
@@ -922,10 +922,10 @@ static WORD TTLDim(WORD type)
if (Err!=0) return Err;
if (type == RsvIntDim) {
- Err = NewIntAryVar(Name, size);
+ Err = NewIntAryVar(Name, (int)size);
}
else { // type == RsvStrDim
- Err = NewStrAryVar(Name, size);
+ Err = NewStrAryVar(Name, (int)size);
}
return Err;
}
@@ -933,7 +933,7 @@ static WORD TTLDim(WORD type)
static WORD TTLDisconnect(void)
{
WORD Err;
- int Val = 1;
+ long long Val = 1;
char Str[21];
Err = 0;
@@ -961,7 +961,7 @@ static WORD TTLDispStr(void)
TStrVal Str, buff;
WORD Err;
TVariableType ValType;
- int Val;
+ long long Val;
if (! Linked)
return ErrLinkFirst;
@@ -999,7 +999,7 @@ static WORD TTLDispStr(void)
static WORD TTLDo(void)
{
WORD WId, Err;
- int Val = 1;
+ long long Val = 1;
Err = 0;
if (CheckParameterGiven()) {
@@ -1046,9 +1046,9 @@ static WORD TTLElse(void)
return 0;
}
-static int CheckElseIf(LPWORD Err)
+static long long CheckElseIf(LPWORD Err)
{
- int Val;
+ long long Val;
WORD WId;
*Err = 0;
@@ -1064,7 +1064,7 @@ static int CheckElseIf(LPWORD Err)
static WORD TTLElseIf(void)
{
WORD Err;
- int Val;
+ long long Val;
Val = CheckElseIf(&Err);
if (Err!=0) return Err;
@@ -1104,7 +1104,7 @@ static WORD TTLEndIf(void)
static WORD TTLEndWhile(BOOL mode)
{
WORD Err;
- int Val = mode;
+ long long Val = mode;
Err = 0;
if (CheckParameterGiven()) {
@@ -2095,7 +2095,7 @@ static WORD TTLFileWrite(BOOL addCRLF)
WORD Err, P;
int fhi;
HANDLE FH;
- int Val;
+ long long Val;
TStrVal Str;
Err = 0;
@@ -3038,7 +3038,7 @@ static WORD TTLIfDefined(void)
{
WORD Err;
TVariableType VarType;
- int Val;
+ long long Val;
GetVarType(&VarType,&Val,&Err);
@@ -3074,7 +3074,7 @@ static WORD TTLIf(void)
{
WORD Err, Tmp, WId;
TVariableType ValType;
- int Val;
+ long long Val;
if (! GetExpression(&ValType,&Val,&Err))
return ErrSyntax;
@@ -3304,7 +3304,7 @@ static WORD TTLLogOpen(void)
static WORD TTLLoop(void)
{
WORD WId, Err;
- int Val = 1;
+ long long Val = 1;
Err = 0;
if (CheckParameterGiven()) {
@@ -3921,7 +3921,7 @@ static WORD GetParamStrings(void)
TStrVal Str;
WORD Err;
TVariableType ValType;
- int Val;
+ long long Val;
BOOL EndOfLine;
EndOfLine = FALSE;
@@ -4033,7 +4033,7 @@ static WORD GetBroadcastString(char *buff, int bufflen, BOOL crlf)
TStrVal Str;
WORD Err;
TVariableType ValType;
- int Val;
+ long long Val;
char tmp[3];
buff[0] = '\0';
@@ -4283,7 +4283,7 @@ static WORD TTLSetEnv(void)
static WORD TTLSetExitCode(void)
{
WORD Err;
- int Val;
+ long long Val;
Err = 0;
GetIntVal(&Val,&Err);
@@ -4328,7 +4328,7 @@ static WORD TTLSetFileAttr(void)
static WORD TTLSetSync(void)
{
WORD Err;
- int Val;
+ long long Val;
Err = 0;
GetIntVal(&Val,&Err);
@@ -4378,7 +4378,7 @@ static WORD TTLSetTime(void)
static WORD TTLShow(void)
{
WORD Err;
- int Val;
+ long long Val;
Err = 0;
GetIntVal(&Val,&Err);
@@ -5457,11 +5457,28 @@ static WORD TTLUnlink(void)
}
+// int64 varname — 64ビット整数変数の宣言
+static WORD TTLInt64Decl(void)
+{
+ WORD Err, WordId;
+ TVariableType VarType;
+ TName Name;
+ TVarId VarId;
+
+ Err = 0;
+ if (! GetIdentifier(Name)) return ErrSyntax;
+ if (CheckReservedWord(Name, &WordId)) return ErrSyntax;
+ if (CheckVar(Name, &VarType, &VarId)) return ErrSyntax;
+ if (GetFirstChar() != 0) return ErrSyntax;
+
+ if (! NewInt64Var(Name, 0)) return ErrTooManyVar;
+ return 0;
+}
+
static WORD TTLUptime(void)
{
WORD Err;
TVarId VarId;
- DWORD tick;
Err = 0;
GetIntVar(&VarId,&Err);
@@ -5469,11 +5486,10 @@ static WORD TTLUptime(void)
Err = ErrSyntax;
if (Err!=0) return Err;
- // Windows OSが起動してからの経過時間(ミリ秒)を取得する。
- // マクロ変数は32bitのため下位32bitのみ格納する。
- tick = (DWORD)GetTickCount64();
-
- SetIntVal(VarId, tick);
+ // SetIntVal が変数の型に応じて格納する:
+ // TypInteger64 → 64ビット全体を格納
+ // TypInteger → 下位32ビットのみ格納(従来の動作を維持)
+ SetIntVal(VarId, (long long)GetTickCount64());
return Err;
}
@@ -5693,7 +5709,7 @@ static WORD TTLWaitRecv(void)
static WORD TTLWhile(BOOL mode)
{
WORD Err;
- int Val = mode;
+ long long Val = mode;
Err = 0;
if (CheckParameterGiven()) {
@@ -5896,7 +5912,7 @@ static int ExecCmnd(void)
TStrVal Str;
TName Cmnd;
TVariableType ValType, VarType;
- int Val;
+ long long Val;
Err = 0;
@@ -6184,6 +6200,8 @@ static int ExecCmnd(void)
Err = TTLInputBox(FALSE); break;
case RsvInt2Str:
Err = TTLInt2Str(); break;
+ case RsvInt64:
+ Err = TTLInt64Decl(); break;
case RsvIntDim:
case RsvStrDim:
Err = TTLDim(WId); break;
@@ -6437,9 +6455,13 @@ static int ExecCmnd(void)
}
}
if (Err) return Err;
- if (VarType==ValType) {
- switch (ValType) {
- case TypInteger: SetIntVal(VarId,Val); break;
+ if (VarType==ValType ||
+ (VarType==TypInteger && ValType==TypInteger64) ||
+ (VarType==TypInteger64 && ValType==TypInteger)) {
+ switch (VarType) {
+ case TypInteger:
+ case TypInteger64:
+ SetIntVal(VarId,Val); break;
case TypString:
if (StrConst)
SetStrVal(VarId,Str);
@@ -6461,6 +6483,7 @@ static int ExecCmnd(void)
else {
switch (ValType) {
case TypInteger: E = NewIntVar(Cmnd,Val); break;
+ case TypInteger64: E = NewInt64Var(Cmnd,Val); break;
case TypString:
if (StrConst)
E = NewStrVar(Cmnd,Str);
diff --git a/teraterm/ttpmacro/ttmparse.cpp b/teraterm/ttpmacro/ttmparse.cpp
index d24234cfc..567133cca 100644
--- a/teraterm/ttpmacro/ttmparse.cpp
+++ b/teraterm/ttpmacro/ttmparse.cpp
@@ -74,6 +74,7 @@ typedef struct {
union {
char *Str;
int Int;
+ long long Int64;
TLab Lab;
TIntAry IntAry;
TStrAry StrAry;
@@ -291,6 +292,7 @@ BOOL CheckReservedWord(PCHAR Str, LPWORD WordId)
else if (_stricmp(Str,"include")==0) *WordId = RsvInclude ;
else if (_stricmp(Str,"inputbox")==0) *WordId = RsvInputBox;
else if (_stricmp(Str,"int2str")==0) *WordId = RsvInt2Str;
+ else if (_stricmp(Str,"int64")==0) *WordId = RsvInt64;
else if (_stricmp(Str,"intdim")==0) *WordId = RsvIntDim;
else if (_stricmp(Str,"ispassword")==0) *WordId = RsvIsPassword; // add 'ispassword' (2012.5.24 yutaka)
else if (_stricmp(Str,"ispassword2")==0) *WordId = RsvIsPassword2;
@@ -815,7 +817,7 @@ BOOL GetString(PCHAR Str, LPWORD Err)
return TRUE;
}
-BOOL GetNumber(int *Num)
+BOOL GetNumber(long long *Num)
{
BYTE b;
@@ -883,10 +885,17 @@ static Variable_t *NewVar(const char *name, TVariableType type)
return v;
}
-BOOL NewIntVar(const char *Name, int InitVal)
+BOOL NewIntVar(const char *Name, long long InitVal)
{
Variable_t *v = NewVar(Name, TypeInteger);
- v->Value.Int = InitVal;
+ v->Value.Int = (int)InitVal;
+ return TRUE;
+}
+
+BOOL NewInt64Var(const char *Name, long long InitVal)
+{
+ Variable_t *v = NewVar(Name, TypeInteger64);
+ v->Value.Int64 = InitVal;
return TRUE;
}
@@ -976,7 +985,12 @@ void CopyLabel(WORD ILabel, BINT *Ptr, LPWORD Level)
* Evaluate following operator.
* not, ~, !, +(unary), -(unary)
*/
-static BOOL GetFactor(TVariableType *ValType, int *Val, LPWORD Err)
+static BOOL IsIntType(TVariableType t)
+{
+ return t == TypInteger || t == TypInteger64;
+}
+
+static BOOL GetFactor(TVariableType *ValType, long long *Val, LPWORD Err)
{
TName Name;
WORD P, WId;
@@ -988,7 +1002,7 @@ static BOOL GetFactor(TVariableType *ValType, int *Val, LPWORD Err)
if (GetIdentifier(Name)) {
if (CheckReservedWord(Name,&WId)) {
if (GetFactor(ValType, Val, Err)) {
- if ((*Err==0) && (*ValType!=TypInteger))
+ if ((*Err==0) && (!IsIntType(*ValType)))
*Err = ErrTypeMismatch;
switch (WId) {
case RsvBNot: *Val = ~(*Val); break;
@@ -1005,6 +1019,9 @@ static BOOL GetFactor(TVariableType *ValType, int *Val, LPWORD Err)
case TypInteger:
*Val = Variables[VarId].Value.Int;
break;
+ case TypInteger64:
+ *Val = Variables[VarId].Value.Int64;
+ break;
case TypString: *Val = VarId; break;
case TypIntArray:
if (GetIndex(&Index, Err)) {
@@ -1042,7 +1059,7 @@ static BOOL GetFactor(TVariableType *ValType, int *Val, LPWORD Err)
*ValType = TypInteger;
else if (GetOperator(&WId)) {
if (GetFactor(ValType, Val, Err)) {
- if ((*Err==0) && (*ValType != TypInteger))
+ if ((*Err==0) && (!IsIntType(*ValType)))
*Err = ErrTypeMismatch;
switch (WId) {
case RsvPlus: break;
@@ -1078,11 +1095,11 @@ static BOOL GetFactor(TVariableType *ValType, int *Val, LPWORD Err)
* Evaluate following operator.
* *, /, %
*/
-static BOOL EvalMultiplication(TVariableType *ValType, int *Val, LPWORD Err)
+static BOOL EvalMultiplication(TVariableType *ValType, long long *Val, LPWORD Err)
{
WORD P, Er;
TVariableType Type;
- int Val1, Val2;
+ long long Val1, Val2;
WORD WId;
if (! GetFactor(&Type, &Val1, &Er)) return FALSE;
@@ -1090,7 +1107,7 @@ static BOOL EvalMultiplication(TVariableType *ValType, int *Val, LPWORD Err)
*Val = Val1;
*Err = Er;
if (Er) return TRUE;
- if (Type!=TypInteger) return TRUE;
+ if (!IsIntType(Type)) return TRUE;
while (TRUE) {
P = LinePtr;
@@ -1116,10 +1133,11 @@ static BOOL EvalMultiplication(TVariableType *ValType, int *Val, LPWORD Err)
return TRUE;
}
- if (Type!=TypInteger) {
+ if (!IsIntType(Type)) {
*Err = ErrTypeMismatch;
return TRUE;
}
+ if (Type == TypInteger64) *ValType = TypInteger64;
if (Val2 == 0 && WId != RsvMul) {
*Err = ErrDivByZero;
@@ -1140,11 +1158,11 @@ static BOOL EvalMultiplication(TVariableType *ValType, int *Val, LPWORD Err)
* Evaluate following operator.
* +, -
*/
-static BOOL EvalAddition(TVariableType *ValType, int *Val, LPWORD Err)
+static BOOL EvalAddition(TVariableType *ValType, long long *Val, LPWORD Err)
{
WORD P, Er;
TVariableType Type;
- int Val1, Val2;
+ long long Val1, Val2;
WORD WId;
if (! EvalMultiplication(&Type, &Val1, &Er)) return FALSE;
@@ -1152,7 +1170,7 @@ static BOOL EvalAddition(TVariableType *ValType, int *Val, LPWORD Err)
*Val = Val1;
*Err = Er;
if (Er) return TRUE;
- if (Type!=TypInteger) return TRUE;
+ if (!IsIntType(Type)) return TRUE;
while (TRUE) {
P = LinePtr;
@@ -1177,10 +1195,11 @@ static BOOL EvalAddition(TVariableType *ValType, int *Val, LPWORD Err)
return TRUE;
}
- if (Type!=TypInteger) {
+ if (!IsIntType(Type)) {
*Err = ErrTypeMismatch;
return TRUE;
}
+ if (Type == TypInteger64) *ValType = TypInteger64;
switch (WId) {
case RsvPlus: Val1 = Val1 + Val2; break;
@@ -1195,11 +1214,11 @@ static BOOL EvalAddition(TVariableType *ValType, int *Val, LPWORD Err)
* Evaluate following operator.
* >>, <<, >>>
*/
-static BOOL EvalBitShift(TVariableType *ValType, int *Val, LPWORD Err)
+static BOOL EvalBitShift(TVariableType *ValType, long long *Val, LPWORD Err)
{
WORD P, Er;
TVariableType Type;
- int Val1, Val2;
+ long long Val1, Val2;
WORD WId;
if (! EvalAddition(&Type, &Val1, &Er)) return FALSE;
@@ -1207,7 +1226,7 @@ static BOOL EvalBitShift(TVariableType *ValType, int *Val, LPWORD Err)
*Val = Val1;
*Err = Er;
if (Er) return TRUE;
- if (Type!=TypInteger) return TRUE;
+ if (!IsIntType(Type)) return TRUE;
while (TRUE) {
P = LinePtr;
@@ -1233,32 +1252,36 @@ static BOOL EvalBitShift(TVariableType *ValType, int *Val, LPWORD Err)
return TRUE;
}
- if (Type!=TypInteger) {
+ if (!IsIntType(Type)) {
*Err = ErrTypeMismatch;
return TRUE;
}
+ if (Type == TypInteger64) *ValType = TypInteger64;
if (WId == RsvALShift)
Val2 = -Val2;
- if (Val2 <= -(int)INT_BIT) { /* Val2 <= -32 */
+ const long long valbits = (*ValType == TypInteger64) ? 64 : (long long)INT_BIT;
+ if (Val2 <= -valbits) {
Val1 = 0;
- } else if (Val2 < 0 ) { /* -32 < Val2 < 0 */
+ } else if (Val2 < 0) {
Val1 = Val1 << -Val2;
- } else if (Val2 == 0 ) { /* Val2 == 0 */
+ } else if (Val2 == 0) {
; /* do nothing */
- } else if (Val2 < INT_BIT) { /* 0 < Val2 < 32 */
+ } else if (Val2 < valbits) {
if (WId == RsvLRShift) {
- // use unsigned int for logical right shift
- Val1 = (unsigned int)Val1 >> Val2;
+ if (*ValType == TypInteger64)
+ Val1 = (unsigned long long)Val1 >> Val2;
+ else
+ Val1 = (unsigned int)Val1 >> Val2;
} else {
Val1 = Val1 >> Val2;
}
- } else { /* Val2 >= 32 */
+ } else {
if (Val1 > 0 || WId == RsvLRShift) {
Val1 = 0;
} else {
- Val1 = ~0;
+ Val1 = ~0LL;
}
}
*Val = Val1;
@@ -1270,11 +1293,11 @@ static BOOL EvalBitShift(TVariableType *ValType, int *Val, LPWORD Err)
* Evaluate following operator.
* &
*/
-static BOOL EvalBitAnd(TVariableType *ValType, int *Val, LPWORD Err)
+static BOOL EvalBitAnd(TVariableType *ValType, long long *Val, LPWORD Err)
{
WORD P, Er;
TVariableType Type;
- int Val1, Val2;
+ long long Val1, Val2;
WORD WId;
if (! EvalBitShift(&Type, &Val1, &Er)) return FALSE;
@@ -1282,7 +1305,7 @@ static BOOL EvalBitAnd(TVariableType *ValType, int *Val, LPWORD Err)
*Val = Val1;
*Err = Er;
if (Er) return TRUE;
- if (Type!=TypInteger) return TRUE;
+ if (!IsIntType(Type)) return TRUE;
while (TRUE) {
P = LinePtr;
@@ -1303,10 +1326,11 @@ static BOOL EvalBitAnd(TVariableType *ValType, int *Val, LPWORD Err)
return TRUE;
}
- if (Type!=TypInteger) {
+ if (!IsIntType(Type)) {
*Err = ErrTypeMismatch;
return TRUE;
}
+ if (Type == TypInteger64) *ValType = TypInteger64;
Val1 = Val1 & Val2;
*Val = Val1;
@@ -1318,11 +1342,11 @@ static BOOL EvalBitAnd(TVariableType *ValType, int *Val, LPWORD Err)
* Evaluate following operator.
* ^
*/
-static BOOL EvalBitXor(TVariableType *ValType, int *Val, LPWORD Err)
+static BOOL EvalBitXor(TVariableType *ValType, long long *Val, LPWORD Err)
{
WORD P, Er;
TVariableType Type;
- int Val1, Val2;
+ long long Val1, Val2;
WORD WId;
if (! EvalBitAnd(&Type, &Val1, &Er)) return FALSE;
@@ -1330,7 +1354,7 @@ static BOOL EvalBitXor(TVariableType *ValType, int *Val, LPWORD Err)
*Val = Val1;
*Err = Er;
if (Er) return TRUE;
- if (Type!=TypInteger) return TRUE;
+ if (!IsIntType(Type)) return TRUE;
while (TRUE) {
P = LinePtr;
@@ -1351,10 +1375,11 @@ static BOOL EvalBitXor(TVariableType *ValType, int *Val, LPWORD Err)
return TRUE;
}
- if (Type!=TypInteger) {
+ if (!IsIntType(Type)) {
*Err = ErrTypeMismatch;
return TRUE;
}
+ if (Type == TypInteger64) *ValType = TypInteger64;
Val1 = Val1 ^ Val2;
*Val = Val1;
@@ -1366,11 +1391,11 @@ static BOOL EvalBitXor(TVariableType *ValType, int *Val, LPWORD Err)
* Evaluate following operator.
* |
*/
-static BOOL EvalBitOr(TVariableType *ValType, int *Val, LPWORD Err)
+static BOOL EvalBitOr(TVariableType *ValType, long long *Val, LPWORD Err)
{
WORD P, Er;
TVariableType Type;
- int Val1, Val2;
+ long long Val1, Val2;
WORD WId;
if (! EvalBitXor(&Type, &Val1, &Er)) return FALSE;
@@ -1378,7 +1403,7 @@ static BOOL EvalBitOr(TVariableType *ValType, int *Val, LPWORD Err)
*Val = Val1;
*Err = Er;
if (Er) return TRUE;
- if (Type!=TypInteger) return TRUE;
+ if (!IsIntType(Type)) return TRUE;
while (TRUE) {
P = LinePtr;
@@ -1399,10 +1424,11 @@ static BOOL EvalBitOr(TVariableType *ValType, int *Val, LPWORD Err)
return TRUE;
}
- if (Type!=TypInteger) {
+ if (!IsIntType(Type)) {
*Err = ErrTypeMismatch;
return TRUE;
}
+ if (Type == TypInteger64) *ValType = TypInteger64;
Val1 = Val1 | Val2;
*Val = Val1;
@@ -1414,11 +1440,11 @@ static BOOL EvalBitOr(TVariableType *ValType, int *Val, LPWORD Err)
* Evaluate following operator.
* <, >, <=, >=
*/
-static BOOL EvalGreater(TVariableType *ValType, int *Val, LPWORD Err)
+static BOOL EvalGreater(TVariableType *ValType, long long *Val, LPWORD Err)
{
WORD P, Er;
TVariableType Type;
- int Val1, Val2;
+ long long Val1, Val2;
WORD WId;
if (! EvalBitOr(&Type, &Val1, &Er)) return FALSE;
@@ -1426,7 +1452,7 @@ static BOOL EvalGreater(TVariableType *ValType, int *Val, LPWORD Err)
*Val = Val1;
*Err = Er;
if (Er) return TRUE;
- if (Type!=TypInteger) return TRUE;
+ if (!IsIntType(Type)) return TRUE;
while (TRUE) {
P = LinePtr;
@@ -1453,7 +1479,7 @@ static BOOL EvalGreater(TVariableType *ValType, int *Val, LPWORD Err)
return TRUE;
}
- if (Type!=TypInteger) {
+ if (!IsIntType(Type)) {
*Err = ErrTypeMismatch;
return TRUE;
}
@@ -1464,6 +1490,7 @@ static BOOL EvalGreater(TVariableType *ValType, int *Val, LPWORD Err)
case RsvLE: Val1 = (Val1<=Val2); break;
case RsvGE: Val1 = (Val1>=Val2); break;
}
+ *ValType = TypInteger;
*Val = Val1;
}
}
@@ -1473,11 +1500,11 @@ static BOOL EvalGreater(TVariableType *ValType, int *Val, LPWORD Err)
* Evaluate following operator.
* =, ==, <>, !=
*/
-static BOOL EvalEqual(TVariableType *ValType, int *Val, LPWORD Err)
+static BOOL EvalEqual(TVariableType *ValType, long long *Val, LPWORD Err)
{
WORD P, Er;
TVariableType Type;
- int Val1, Val2;
+ long long Val1, Val2;
WORD WId;
if (! EvalGreater(&Type, &Val1, &Er)) return FALSE;
@@ -1485,7 +1512,7 @@ static BOOL EvalEqual(TVariableType *ValType, int *Val, LPWORD Err)
*Val = Val1;
*Err = Er;
if (Er) return TRUE;
- if (Type!=TypInteger) return TRUE;
+ if (!IsIntType(Type)) return TRUE;
while (TRUE) {
P = LinePtr;
@@ -1510,7 +1537,7 @@ static BOOL EvalEqual(TVariableType *ValType, int *Val, LPWORD Err)
return TRUE;
}
- if (Type!=TypInteger) {
+ if (!IsIntType(Type)) {
*Err = ErrTypeMismatch;
return TRUE;
}
@@ -1519,6 +1546,7 @@ static BOOL EvalEqual(TVariableType *ValType, int *Val, LPWORD Err)
case RsvEQ: Val1 = (Val1==Val2); break;
case RsvNE: Val1 = (Val1!=Val2); break;
}
+ *ValType = TypInteger;
*Val = Val1;
}
}
@@ -1528,11 +1556,11 @@ static BOOL EvalEqual(TVariableType *ValType, int *Val, LPWORD Err)
* Evaluate following operator.
* &&
*/
-static BOOL EvalLogicalAnd(TVariableType *ValType, int *Val, LPWORD Err)
+static BOOL EvalLogicalAnd(TVariableType *ValType, long long *Val, LPWORD Err)
{
WORD P, Er;
TVariableType Type;
- int Val1, Val2;
+ long long Val1, Val2;
WORD WId;
if (! EvalEqual(&Type, &Val1, &Er)) return FALSE;
@@ -1540,7 +1568,7 @@ static BOOL EvalLogicalAnd(TVariableType *ValType, int *Val, LPWORD Err)
*Val = Val1;
*Err = Er;
if (Er) return TRUE;
- if (Type!=TypInteger) return TRUE;
+ if (!IsIntType(Type)) return TRUE;
while (TRUE) {
P = LinePtr;
@@ -1561,12 +1589,13 @@ static BOOL EvalLogicalAnd(TVariableType *ValType, int *Val, LPWORD Err)
return TRUE;
}
- if (Type!=TypInteger) {
+ if (!IsIntType(Type)) {
*Err = ErrTypeMismatch;
return TRUE;
}
Val1 = Val1 && Val2;
+ *ValType = TypInteger;
*Val = Val1;
}
}
@@ -1576,11 +1605,11 @@ static BOOL EvalLogicalAnd(TVariableType *ValType, int *Val, LPWORD Err)
* Evaluate following operator.
* ||
*/
-BOOL GetExpression(TVariableType *ValType, int *Val, LPWORD Err)
+BOOL GetExpression(TVariableType *ValType, long long *Val, LPWORD Err)
{
WORD P1, P2, Er;
TVariableType Type;
- int Val1, Val2;
+ long long Val1, Val2;
WORD WId;
P1 = LinePtr;
@@ -1595,7 +1624,7 @@ BOOL GetExpression(TVariableType *ValType, int *Val, LPWORD Err)
LinePtr = P1;
return TRUE;
}
- if (Type!=TypInteger) return TRUE;
+ if (!IsIntType(Type)) return TRUE;
while (TRUE) {
P2 = LinePtr;
@@ -1618,7 +1647,7 @@ BOOL GetExpression(TVariableType *ValType, int *Val, LPWORD Err)
return TRUE;
}
- if (Type!=TypInteger) {
+ if (!IsIntType(Type)) {
*Err = ErrTypeMismatch;
LinePtr = P1;
return TRUE;
@@ -1628,11 +1657,12 @@ BOOL GetExpression(TVariableType *ValType, int *Val, LPWORD Err)
case RsvLOr: Val1 = Val1 || Val2; break;
case RsvLXor: Val1 = (Val1 && !Val2) || (!Val1 && Val2); break;
}
+ *ValType = TypInteger;
*Val = Val1;
}
}
-void GetIntVal(int *Val, LPWORD Err)
+void GetIntVal(long long *Val, LPWORD Err)
{
TVariableType ValType;
@@ -1645,24 +1675,34 @@ void GetIntVal(int *Val, LPWORD Err)
return;
}
if (*Err!=0) return;
- if (ValType!=TypInteger)
+ if (ValType!=TypInteger && ValType!=TypInteger64)
*Err = ErrTypeMismatch;
}
-void SetIntVal(TVarId VarId, int Val)
+void GetIntVal(int *Val, LPWORD Err)
+{
+ long long tmp = 0;
+ GetIntVal(&tmp, Err);
+ *Val = (int)tmp;
+}
+
+void SetIntVal(TVarId VarId, long long Val)
{
if (VarId >> 16) {
Variable_t *v = &Variables[(VarId>>16)-1];
int *int_val = &v->Value.IntAry.val[VarId & 0xffff];
- *int_val = Val;
+ *int_val = (int)Val;
}
else {
Variable_t *v = &Variables[VarId];
- v->Value.Int = Val;
+ if (v->Type == TypInteger64)
+ v->Value.Int64 = Val;
+ else
+ v->Value.Int = (int)Val;
}
}
-int CopyIntVal(TVarId VarId)
+long long CopyIntVal(TVarId VarId)
{
Variable_t *v;
if (VarId >> 16) {
@@ -1671,6 +1711,8 @@ int CopyIntVal(TVarId VarId)
}
else {
v = &Variables[VarId];
+ if (v->Type == TypInteger64)
+ return v->Value.Int64;
return v->Value.Int;
}
}
@@ -1687,6 +1729,7 @@ void GetIntVar(PVarId VarId, LPWORD Err)
if (CheckVar(Name, &VarType, VarId)) {
switch (VarType) {
case TypInteger:
+ case TypInteger64:
break;
case TypIntArray:
if (GetIndex(&Index, Err)) {
@@ -1832,7 +1875,7 @@ const char *StrVarPtr(TVarId VarId)
}
// for ifdefined (2006.9.23 maya)
-void GetVarType(TVariableType *ValType, int *Val, LPWORD Err)
+void GetVarType(TVariableType *ValType, long long *Val, LPWORD Err)
{
TName Name;
WORD WId;
@@ -1878,6 +1921,13 @@ void GetVarType(TVariableType *ValType, int *Val, LPWORD Err)
*Err = 0;
}
+void GetVarType(TVariableType *ValType, int *Val, LPWORD Err)
+{
+ long long tmp = 0;
+ GetVarType(ValType, &tmp, Err);
+ *Val = (int)tmp;
+}
+
BOOL GetIndex(int *Index, LPWORD Err)
{
WORD P;
diff --git a/teraterm/ttpmacro/ttmparse.h b/teraterm/ttpmacro/ttmparse.h
index c5bae13b2..70c1c684c 100644
--- a/teraterm/ttpmacro/ttmparse.h
+++ b/teraterm/ttpmacro/ttmparse.h
@@ -79,12 +79,14 @@ typedef enum {
TypLabel = 4,
TypIntArray = 5,
TypStrArray = 6,
+ TypInteger64 = 7,
TypeUnknown = TypUnknown,
TypeInteger = TypInteger,
TypeString = TypString,
TypeLabel = TypLabel,
TypeIntArray = TypIntArray,
TypeStrArray = TypStrArray,
+ TypeInteger64 = TypInteger64,
} TVariableType;
#define RsvBeep 1
@@ -299,6 +301,7 @@ typedef enum {
#define RsvGetTTPos 223
#define RsvSetSerialDelayChar 224
#define RsvSetSerialDelayLine 225
+#define RsvInt64 226
#define RsvOperator 1000
#define RsvBNot 1001
@@ -359,23 +362,26 @@ BOOL CheckReservedWord(PCHAR Str, LPWORD WordId);
BOOL GetLabelName(PCHAR Name);
BOOL GetString(PCHAR Str, LPWORD Err);
BOOL CheckVar(const char *Name, TVariableType *VarType, PVarId VarId);
-BOOL NewIntVar(const char *Name, int InitVal);
+BOOL NewIntVar(const char *Name, long long InitVal);
+BOOL NewInt64Var(const char *Name, long long InitVal);
BOOL NewStrVar(const char *Name, const char *InitVal);
BOOL NewLabVar(const char *Name, BINT InitVal, WORD ILevel);
int NewIntAryVar(const char *Name, int size);
int NewStrAryVar(const char *Name, int size);
void DelLabVar(WORD ILevel);
void CopyLabel(WORD ILabel, BINT *Ptr, LPWORD Level);
-BOOL GetExpression(TVariableType *ValType, int *Val, LPWORD Err);
+BOOL GetExpression(TVariableType *ValType, long long *Val, LPWORD Err);
+void GetIntVal(long long *Val, LPWORD Err);
void GetIntVal(int *Val, LPWORD Err);
-void SetIntVal(TVarId VarId, int Val);
-int CopyIntVal(TVarId VarId);
+void SetIntVal(TVarId VarId, long long Val);
+long long CopyIntVal(TVarId VarId);
void GetIntVar(PVarId VarId, LPWORD Err);
void GetStrVal(PCHAR Str, LPWORD Err);
void GetStrVal2(PCHAR Str, LPWORD Err, BOOL AutoConversion);
void GetStrVar(PVarId VarId, LPWORD Err);
void SetStrVal(TVarId VarId, const char *Str);
const char *StrVarPtr(TVarId VarId);
+void GetVarType(TVariableType *ValType, long long *Val, LPWORD Err);
void GetVarType(TVariableType *ValType, int *Val, LPWORD Err);
TVarId GetIntVarFromArray(TVarId VarId, int Index, LPWORD Err);
TVarId GetStrVarFromArray(TVarId VarId, int Index, LPWORD Err);
diff --git a/tests/wait_timeout.ttl b/tests/wait_timeout.ttl
new file mode 100644
index 000000000..3e2a2e0a3
--- /dev/null
+++ b/tests/wait_timeout.ttl
@@ -0,0 +1,41 @@
+; pause コマンドのタイムアウトテスト
+;
+; GetTickCount64() への置き換え後、タイムアウト機構が
+; 正常動作することを確認する。
+; OS 起動から 49.7 日以上経過した環境でも正しく動作することを想定。
+;
+; 使い方: Tera Term マクロとして単体で実行する(接続不要)
+;
+; int64 変数を使って uptime を 64ビットで取得し、
+; 49.7 日オーバーフローに依存しない経過時間計測を行う。
+
+int64 tick_start
+int64 tick_end
+
+uptime tick_start
+
+; 3 秒間 pause する
+pause 3
+
+uptime tick_end
+
+; 経過時間を計算(ミリ秒)
+elapsed = tick_end - tick_start
+
+; 3000ms ±500ms 以内であることを確認
+if elapsed < 2500 then
+ sprintf2 msg 'NG: pause が早すぎる (%d ms)' elapsed
+ messagebox msg 'pause timeout test'
+ end
+endif
+
+if elapsed > 3500 then
+ sprintf2 msg 'NG: pause が遅すぎる (%d ms)' elapsed
+ messagebox msg 'pause timeout test'
+ end
+endif
+
+sprintf2 msg 'OK: pause が正常に完了した (%d ms)' elapsed
+messagebox msg 'pause timeout test'
+
+end
From 7861672c2d626b7e67a66050ad2bf24565cd782c Mon Sep 17 00:00:00 2001
From: Masaru Tsuchiyama
Date: Thu, 4 Jun 2026 13:38:00 +0900
Subject: [PATCH 03/17] =?UTF-8?q?=E3=83=93=E3=83=AB=E3=83=89=E3=82=A8?=
=?UTF-8?q?=E3=83=A9=E3=83=BC=E4=BF=AE=E6=AD=A3:=20extern"C"=E3=82=AA?=
=?UTF-8?q?=E3=83=BC=E3=83=90=E3=83=BC=E3=83=AD=E3=83=BC=E3=83=89=E5=95=8F?=
=?UTF-8?q?=E9=A1=8C=E3=81=A8=E5=9E=8B=E4=B8=8D=E4=B8=80=E8=87=B4=E3=82=92?=
=?UTF-8?q?=E8=A7=A3=E6=B6=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- GetIntVal/GetVarTypeのint*オーバーロードをextern"C"非互換のため削除
- GetIntVal実装をint*シグネチャに戻し、内部でlong longを使用してlong longに truncate
- GetVarType実装をint*シグネチャに戻す
- GetExpressionを直接呼ばないlong long Valローカル変数をint Valに戻す
- TTLWait内のGetExpression呼び出し用Valをlong longに修正
Co-Authored-By: Claude Sonnet 4.6
---
teraterm/ttpmacro/ttl.cpp | 41 +++++++++++++++++-----------------
teraterm/ttpmacro/ttmparse.cpp | 24 ++++++--------------
teraterm/ttpmacro/ttmparse.h | 2 --
3 files changed, 28 insertions(+), 39 deletions(-)
diff --git a/teraterm/ttpmacro/ttl.cpp b/teraterm/ttpmacro/ttl.cpp
index d7df2c64a..6fc24a03d 100644
--- a/teraterm/ttpmacro/ttl.cpp
+++ b/teraterm/ttpmacro/ttl.cpp
@@ -373,7 +373,7 @@ static WORD TTLCommCmdFile(char Cmd, int Wait)
static WORD TTLCommCmdBin(char Cmd, int Wait)
{
- long long Val;
+ int Val;
WORD Err;
Err = 0;
@@ -394,7 +394,7 @@ static WORD TTLCommCmdBin(char Cmd, int Wait)
static WORD TTLCommCmdDeb(void)
{
- long long Val;
+ int Val;
WORD Err;
Err = 0;
@@ -414,7 +414,7 @@ static WORD TTLCommCmdDeb(void)
static WORD TTLCommCmdInt(char Cmd, int Wait)
{
- long long Val;
+ int Val;
char Str[21];
WORD Err;
@@ -910,7 +910,7 @@ static WORD TTLDim(WORD type)
TVariableType VarType;
TName Name;
TVarId VarId;
- long long size;
+ int size;
Err = 0;
@@ -922,10 +922,10 @@ static WORD TTLDim(WORD type)
if (Err!=0) return Err;
if (type == RsvIntDim) {
- Err = NewIntAryVar(Name, (int)size);
+ Err = NewIntAryVar(Name, size);
}
else { // type == RsvStrDim
- Err = NewStrAryVar(Name, (int)size);
+ Err = NewStrAryVar(Name, size);
}
return Err;
}
@@ -933,7 +933,7 @@ static WORD TTLDim(WORD type)
static WORD TTLDisconnect(void)
{
WORD Err;
- long long Val = 1;
+ int Val = 1;
char Str[21];
Err = 0;
@@ -999,7 +999,7 @@ static WORD TTLDispStr(void)
static WORD TTLDo(void)
{
WORD WId, Err;
- long long Val = 1;
+ int Val = 1;
Err = 0;
if (CheckParameterGiven()) {
@@ -1046,9 +1046,9 @@ static WORD TTLElse(void)
return 0;
}
-static long long CheckElseIf(LPWORD Err)
+static int CheckElseIf(LPWORD Err)
{
- long long Val;
+ int Val;
WORD WId;
*Err = 0;
@@ -1064,7 +1064,7 @@ static long long CheckElseIf(LPWORD Err)
static WORD TTLElseIf(void)
{
WORD Err;
- long long Val;
+ int Val;
Val = CheckElseIf(&Err);
if (Err!=0) return Err;
@@ -1104,7 +1104,7 @@ static WORD TTLEndIf(void)
static WORD TTLEndWhile(BOOL mode)
{
WORD Err;
- long long Val = mode;
+ int Val = mode;
Err = 0;
if (CheckParameterGiven()) {
@@ -2095,7 +2095,7 @@ static WORD TTLFileWrite(BOOL addCRLF)
WORD Err, P;
int fhi;
HANDLE FH;
- long long Val;
+ int Val;
TStrVal Str;
Err = 0;
@@ -3038,7 +3038,7 @@ static WORD TTLIfDefined(void)
{
WORD Err;
TVariableType VarType;
- long long Val;
+ int Val;
GetVarType(&VarType,&Val,&Err);
@@ -3304,7 +3304,7 @@ static WORD TTLLogOpen(void)
static WORD TTLLoop(void)
{
WORD WId, Err;
- long long Val = 1;
+ int Val = 1;
Err = 0;
if (CheckParameterGiven()) {
@@ -4283,7 +4283,7 @@ static WORD TTLSetEnv(void)
static WORD TTLSetExitCode(void)
{
WORD Err;
- long long Val;
+ int Val;
Err = 0;
GetIntVal(&Val,&Err);
@@ -4328,7 +4328,7 @@ static WORD TTLSetFileAttr(void)
static WORD TTLSetSync(void)
{
WORD Err;
- long long Val;
+ int Val;
Err = 0;
GetIntVal(&Val,&Err);
@@ -4378,7 +4378,7 @@ static WORD TTLSetTime(void)
static WORD TTLShow(void)
{
WORD Err;
- long long Val;
+ int Val;
Err = 0;
GetIntVal(&Val,&Err);
@@ -5502,7 +5502,8 @@ static WORD TTLWait(BOOL Ln)
WORD Err;
TVariableType ValType;
TVarId VarId;
- int i, Val;
+ int i;
+ long long Val;
int TimeOut;
ClearWait();
@@ -5709,7 +5710,7 @@ static WORD TTLWaitRecv(void)
static WORD TTLWhile(BOOL mode)
{
WORD Err;
- long long Val = mode;
+ int Val = mode;
Err = 0;
if (CheckParameterGiven()) {
diff --git a/teraterm/ttpmacro/ttmparse.cpp b/teraterm/ttpmacro/ttmparse.cpp
index 567133cca..85d2eab79 100644
--- a/teraterm/ttpmacro/ttmparse.cpp
+++ b/teraterm/ttpmacro/ttmparse.cpp
@@ -1662,27 +1662,24 @@ BOOL GetExpression(TVariableType *ValType, long long *Val, LPWORD Err)
}
}
-void GetIntVal(long long *Val, LPWORD Err)
+void GetIntVal(int *Val, LPWORD Err)
{
TVariableType ValType;
+ long long tmp = 0;
UpdateLineParsePtr();
if (*Err != 0) return;
- if (! GetExpression(&ValType,Val,Err))
+ if (! GetExpression(&ValType, &tmp, Err))
{
*Err = ErrSyntax;
return;
}
if (*Err!=0) return;
- if (ValType!=TypInteger && ValType!=TypInteger64)
+ if (ValType!=TypInteger && ValType!=TypInteger64) {
*Err = ErrTypeMismatch;
-}
-
-void GetIntVal(int *Val, LPWORD Err)
-{
- long long tmp = 0;
- GetIntVal(&tmp, Err);
+ return;
+ }
*Val = (int)tmp;
}
@@ -1875,7 +1872,7 @@ const char *StrVarPtr(TVarId VarId)
}
// for ifdefined (2006.9.23 maya)
-void GetVarType(TVariableType *ValType, long long *Val, LPWORD Err)
+void GetVarType(TVariableType *ValType, int *Val, LPWORD Err)
{
TName Name;
WORD WId;
@@ -1921,13 +1918,6 @@ void GetVarType(TVariableType *ValType, long long *Val, LPWORD Err)
*Err = 0;
}
-void GetVarType(TVariableType *ValType, int *Val, LPWORD Err)
-{
- long long tmp = 0;
- GetVarType(ValType, &tmp, Err);
- *Val = (int)tmp;
-}
-
BOOL GetIndex(int *Index, LPWORD Err)
{
WORD P;
diff --git a/teraterm/ttpmacro/ttmparse.h b/teraterm/ttpmacro/ttmparse.h
index 70c1c684c..999d687e6 100644
--- a/teraterm/ttpmacro/ttmparse.h
+++ b/teraterm/ttpmacro/ttmparse.h
@@ -371,7 +371,6 @@ int NewStrAryVar(const char *Name, int size);
void DelLabVar(WORD ILevel);
void CopyLabel(WORD ILabel, BINT *Ptr, LPWORD Level);
BOOL GetExpression(TVariableType *ValType, long long *Val, LPWORD Err);
-void GetIntVal(long long *Val, LPWORD Err);
void GetIntVal(int *Val, LPWORD Err);
void SetIntVal(TVarId VarId, long long Val);
long long CopyIntVal(TVarId VarId);
@@ -381,7 +380,6 @@ void GetStrVal2(PCHAR Str, LPWORD Err, BOOL AutoConversion);
void GetStrVar(PVarId VarId, LPWORD Err);
void SetStrVal(TVarId VarId, const char *Str);
const char *StrVarPtr(TVarId VarId);
-void GetVarType(TVariableType *ValType, long long *Val, LPWORD Err);
void GetVarType(TVariableType *ValType, int *Val, LPWORD Err);
TVarId GetIntVarFromArray(TVarId VarId, int Index, LPWORD Err);
TVarId GetStrVarFromArray(TVarId VarId, int Index, LPWORD Err);
From b494100f64cd22cca7a0453b6b1ab6dc4c6942bd Mon Sep 17 00:00:00 2001
From: Masaru Tsuchiyama
Date: Thu, 4 Jun 2026 13:45:48 +0900
Subject: [PATCH 04/17] =?UTF-8?q?=E3=83=93=E3=83=AB=E3=83=89=E3=82=A8?=
=?UTF-8?q?=E3=83=A9=E3=83=BC=E4=BF=AE=E6=AD=A3:=20GetStrVal2=E3=81=AEint?=
=?UTF-8?q?=20VarId=E3=82=92long=20long=E3=81=AB=E5=A4=89=E6=9B=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
GetExpressionがlong long*を期待するため、GetStrVal2内のVarIdを
long longに変更し、TypInteger64のstring変換も対応。
Co-Authored-By: Claude Sonnet 4.6
---
teraterm/ttpmacro/ttmparse.cpp | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/teraterm/ttpmacro/ttmparse.cpp b/teraterm/ttpmacro/ttmparse.cpp
index 85d2eab79..1525a7ac3 100644
--- a/teraterm/ttpmacro/ttmparse.cpp
+++ b/teraterm/ttpmacro/ttmparse.cpp
@@ -1768,7 +1768,7 @@ void GetStrVal(PCHAR Str, LPWORD Err)
void GetStrVal2(PCHAR Str, LPWORD Err, BOOL AutoConversion)
{
TVariableType VarType;
- int VarId;
+ long long VarId;
Str[0] = 0;
if (*Err!=0) return;
@@ -1782,8 +1782,9 @@ void GetStrVal2(PCHAR Str, LPWORD Err, BOOL AutoConversion)
strncpy_s(Str, MaxStrLen, StrVarPtr((TVarId)VarId), _TRUNCATE);
break;
case TypInteger:
+ case TypInteger64:
if (AutoConversion)
- _snprintf_s(Str, MaxStrLen, _TRUNCATE, "%d", VarId);
+ _snprintf_s(Str, MaxStrLen, _TRUNCATE, "%lld", VarId);
else
*Err = ErrTypeMismatch;
break;
From bed144274fe37ea83a13ae7785ee84b920151918 Mon Sep 17 00:00:00 2001
From: Masaru Tsuchiyama
Date: Thu, 4 Jun 2026 13:58:35 +0900
Subject: [PATCH 05/17] =?UTF-8?q?uptime=20=E3=82=92=20int,=20uptime64=20?=
=?UTF-8?q?=E3=82=92=20int64=20=E5=B0=82=E7=94=A8=E3=82=B3=E3=83=9E?=
=?UTF-8?q?=E3=83=B3=E3=83=89=E3=81=AB=E5=88=86=E9=9B=A2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- uptime: 従来通り下位32ビットのみ格納(既存動作を維持)
- uptime64: 新規コマンド。int64変数に64ビット全体を格納し、
OS起動から49.7日以上経過しても正確な時刻取得が可能
- wait_timeout.ttl: uptime → uptime64 に変更
Co-Authored-By: Claude Sonnet 4.6
---
teraterm/ttpmacro/ttl.cpp | 26 +++++++++++++++++++++++---
teraterm/ttpmacro/ttmparse.cpp | 1 +
teraterm/ttpmacro/ttmparse.h | 1 +
tests/wait_timeout.ttl | 6 +++---
4 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/teraterm/ttpmacro/ttl.cpp b/teraterm/ttpmacro/ttl.cpp
index 6fc24a03d..ad0e9a760 100644
--- a/teraterm/ttpmacro/ttl.cpp
+++ b/teraterm/ttpmacro/ttl.cpp
@@ -5479,6 +5479,7 @@ static WORD TTLUptime(void)
{
WORD Err;
TVarId VarId;
+ DWORD tick;
Err = 0;
GetIntVar(&VarId,&Err);
@@ -5486,9 +5487,26 @@ static WORD TTLUptime(void)
Err = ErrSyntax;
if (Err!=0) return Err;
- // SetIntVal が変数の型に応じて格納する:
- // TypInteger64 → 64ビット全体を格納
- // TypInteger → 下位32ビットのみ格納(従来の動作を維持)
+ // Windows OSが起動してからの経過時間(ミリ秒)を取得する。
+ // マクロ変数は32bitのため下位32bitのみ格納する。
+ tick = (DWORD)GetTickCount64();
+ SetIntVal(VarId, tick);
+
+ return Err;
+}
+
+static WORD TTLUptime64(void)
+{
+ WORD Err;
+ TVarId VarId;
+
+ Err = 0;
+ GetIntVar(&VarId,&Err);
+ if ((Err==0) && (GetFirstChar()!=0))
+ Err = ErrSyntax;
+ if (Err!=0) return Err;
+
+ // int64変数にOS起動からの経過時間(ミリ秒)を64ビットで格納する。
SetIntVal(VarId, (long long)GetTickCount64());
return Err;
@@ -6382,6 +6400,8 @@ static int ExecCmnd(void)
Err = TTLWhile(FALSE); break;
case RsvUptime:
Err = TTLUptime(); break;
+ case RsvUptime64:
+ Err = TTLUptime64(); break;
case RsvVar2Clipb:
Err = TTLVar2Clipb(); break; // add 'var2clipb' (2006.9.17 maya)
case RsvWaitRegex:
diff --git a/teraterm/ttpmacro/ttmparse.cpp b/teraterm/ttpmacro/ttmparse.cpp
index 1525a7ac3..970e1d7fc 100644
--- a/teraterm/ttpmacro/ttmparse.cpp
+++ b/teraterm/ttpmacro/ttmparse.cpp
@@ -415,6 +415,7 @@ BOOL CheckReservedWord(PCHAR Str, LPWORD WordId)
case 'u':
if (_stricmp(Str,"unlink")==0) *WordId = RsvUnlink;
else if (_stricmp(Str,"until")==0) *WordId = RsvUntil;
+ else if (_stricmp(Str,"uptime64")==0) *WordId = RsvUptime64;
else if (_stricmp(Str,"uptime")==0) *WordId = RsvUptime;
break;
case 'v':
diff --git a/teraterm/ttpmacro/ttmparse.h b/teraterm/ttpmacro/ttmparse.h
index 999d687e6..5de9466bc 100644
--- a/teraterm/ttpmacro/ttmparse.h
+++ b/teraterm/ttpmacro/ttmparse.h
@@ -302,6 +302,7 @@ typedef enum {
#define RsvSetSerialDelayChar 224
#define RsvSetSerialDelayLine 225
#define RsvInt64 226
+#define RsvUptime64 227
#define RsvOperator 1000
#define RsvBNot 1001
diff --git a/tests/wait_timeout.ttl b/tests/wait_timeout.ttl
index 3e2a2e0a3..2f96e86e4 100644
--- a/tests/wait_timeout.ttl
+++ b/tests/wait_timeout.ttl
@@ -6,18 +6,18 @@
;
; 使い方: Tera Term マクロとして単体で実行する(接続不要)
;
-; int64 変数を使って uptime を 64ビットで取得し、
+; uptime64 で 64ビットの経過時間を取得し、
; 49.7 日オーバーフローに依存しない経過時間計測を行う。
int64 tick_start
int64 tick_end
-uptime tick_start
+uptime64 tick_start
; 3 秒間 pause する
pause 3
-uptime tick_end
+uptime64 tick_end
; 経過時間を計算(ミリ秒)
elapsed = tick_end - tick_start
From c344e78ce65667f87d731ea3f4696105825d8d2c Mon Sep 17 00:00:00 2001
From: Masaru Tsuchiyama
Date: Thu, 4 Jun 2026 14:12:39 +0900
Subject: [PATCH 06/17] =?UTF-8?q?=E7=A9=BA=E8=A1=8C=E3=81=AE=E4=BF=AE?=
=?UTF-8?q?=E6=AD=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-Authored-By: Claude Sonnet 4.6
---
teraterm/ttpmacro/ttl.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/teraterm/ttpmacro/ttl.cpp b/teraterm/ttpmacro/ttl.cpp
index ad0e9a760..06535c57a 100644
--- a/teraterm/ttpmacro/ttl.cpp
+++ b/teraterm/ttpmacro/ttl.cpp
@@ -5490,6 +5490,7 @@ static WORD TTLUptime(void)
// Windows OSが起動してからの経過時間(ミリ秒)を取得する。
// マクロ変数は32bitのため下位32bitのみ格納する。
tick = (DWORD)GetTickCount64();
+
SetIntVal(VarId, tick);
return Err;
From 1b8bc93ee8eced2e899db58e32b898f9d8ac9a3f Mon Sep 17 00:00:00 2001
From: Masaru Tsuchiyama
Date: Thu, 4 Jun 2026 15:06:37 +0900
Subject: [PATCH 07/17] =?UTF-8?q?uptime64=20=E3=81=AE=E3=83=86=E3=82=B9?=
=?UTF-8?q?=E3=83=88=20ttl?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
tests/wait_timeout_connected.ttl | 49 ++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
create mode 100644 tests/wait_timeout_connected.ttl
diff --git a/tests/wait_timeout_connected.ttl b/tests/wait_timeout_connected.ttl
new file mode 100644
index 000000000..96c97ba94
--- /dev/null
+++ b/tests/wait_timeout_connected.ttl
@@ -0,0 +1,49 @@
+; wait コマンドのタイムアウトテスト(接続必要)
+;
+; GetTickCount64() への置き換え後、wait コマンドのタイムアウトが
+; 正常動作することを確認する。
+; OS 起動から 49.7 日以上経過した環境でも正しく動作することを想定。
+;
+; 使い方: SSH/Telnet 等でホストに接続した状態で実行する。
+;
+; uptime64 で 64ビットの経過時間を取得し、
+; 49.7 日オーバーフローに依存しない経過時間計測を行う。
+
+int64 tick_start
+int64 tick_end
+
+timeout = 3
+
+uptime64 tick_start
+
+; 出現しない文字列を wait で待ち、3 秒でタイムアウトさせる
+wait 'XXXXXXXXXX_NEVER_APPEAR_XXXXXXXXXX'
+
+uptime64 tick_end
+
+; タイムアウトで抜けたことを確認 (result == 1)
+if result <> 1 then
+ messagebox 'NG: wait がタイムアウトしなかった' 'wait timeout test'
+ end
+endif
+
+; 経過時間を計算(ミリ秒)
+elapsed = tick_end - tick_start
+
+; 3000ms ±500ms 以内であることを確認
+if elapsed < 2500 then
+ sprintf2 msg 'NG: タイムアウトが早すぎる (%d ms)' elapsed
+ messagebox msg 'wait timeout test'
+ end
+endif
+
+if elapsed > 3500 then
+ sprintf2 msg 'NG: タイムアウトが遅すぎる (%d ms)' elapsed
+ messagebox msg 'wait timeout test'
+ end
+endif
+
+sprintf2 msg 'OK: wait が正常にタイムアウトした (%d ms)' elapsed
+messagebox msg 'wait timeout test'
+
+end
From 55e4cbab725a0e24aff0290e56fcea446587ebc5 Mon Sep 17 00:00:00 2001
From: Masaru Tsuchiyama
Date: Thu, 4 Jun 2026 15:12:19 +0900
Subject: [PATCH 08/17] =?UTF-8?q?uptime=20=E3=82=B3=E3=83=9E=E3=83=B3?=
=?UTF-8?q?=E3=83=89=E3=81=AE=E3=83=86=E3=82=B9=E3=83=88=20TTL=20=E3=82=92?=
=?UTF-8?q?=E8=BF=BD=E5=8A=A0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
wait_timeout.ttl と同じ構造で、uptime(32bit int版)が
3秒の pause で正確に経過時間を計測できることを確認する。
Co-Authored-By: Claude Sonnet 4.6
---
tests/uptime_test.ttl | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
create mode 100644 tests/uptime_test.ttl
diff --git a/tests/uptime_test.ttl b/tests/uptime_test.ttl
new file mode 100644
index 000000000..20719a12b
--- /dev/null
+++ b/tests/uptime_test.ttl
@@ -0,0 +1,38 @@
+; uptime コマンドのテスト(接続不要)
+;
+; GetTickCount64() への置き換え後、uptime コマンドが
+; 正常動作することを確認する。
+; uptime は OS 起動からの経過時間(ミリ秒)の下位 32 ビットを
+; int 変数に格納する。
+;
+; 使い方: Tera Term マクロとして単体で実行する(接続不要)
+
+uptime tick_start
+
+; 3 秒間 pause する
+pause 3
+
+uptime tick_end
+
+; 経過時間を計算(ミリ秒)
+; 注意: 32bit のため 49.7 日でオーバーフローするが、
+; 短時間の計測では影響なし
+elapsed = tick_end - tick_start
+
+; 3000ms ±500ms 以内であることを確認
+if elapsed < 2500 then
+ sprintf2 msg 'NG: pause が早すぎる (%d ms)' elapsed
+ messagebox msg 'uptime test'
+ end
+endif
+
+if elapsed > 3500 then
+ sprintf2 msg 'NG: pause が遅すぎる (%d ms)' elapsed
+ messagebox msg 'uptime test'
+ end
+endif
+
+sprintf2 msg 'OK: pause が正常に完了した (%d ms)' elapsed
+messagebox msg 'uptime test'
+
+end
From fc8ba121af523cf04ac77ed32fde97c2718b56a0 Mon Sep 17 00:00:00 2001
From: Masaru Tsuchiyama
Date: Thu, 4 Jun 2026 15:13:04 +0900
Subject: [PATCH 09/17] =?UTF-8?q?wait=5Ftimeout.ttl=20=E3=82=92=20uptime64?=
=?UTF-8?q?=5Ftest.ttl=20=E3=81=AB=E6=94=B9=E5=90=8D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
テスト内容(uptime64コマンドの動作確認)に合わせてファイル名を変更。
Co-Authored-By: Claude Sonnet 4.6
---
tests/{wait_timeout.ttl => uptime64_test.ttl} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename tests/{wait_timeout.ttl => uptime64_test.ttl} (100%)
diff --git a/tests/wait_timeout.ttl b/tests/uptime64_test.ttl
similarity index 100%
rename from tests/wait_timeout.ttl
rename to tests/uptime64_test.ttl
From bd11ce7b980250a62d18f5f1361c5178b0b28170 Mon Sep 17 00:00:00 2001
From: Masaru Tsuchiyama
Date: Thu, 4 Jun 2026 15:18:19 +0900
Subject: [PATCH 10/17] =?UTF-8?q?int64=20=E5=A4=89=E6=95=B0=E3=81=AE?=
=?UTF-8?q?=E7=AE=97=E8=A1=93=E3=83=BB=E6=AF=94=E8=BC=83=E3=83=86=E3=82=B9?=
=?UTF-8?q?=E3=83=88=20TTL=20=E3=82=92=E8=BF=BD=E5=8A=A0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
32ビットを超える値($80000000, $100000000, 10000000000 等)を使い、
int64 の加減乗除・剰余・比較演算が正しく動作することを確認する。
Co-Authored-By: Claude Sonnet 4.6
---
tests/int64_arith_test.ttl | 129 +++++++++++++++++++++++++++++++++++++
1 file changed, 129 insertions(+)
create mode 100644 tests/int64_arith_test.ttl
diff --git a/tests/int64_arith_test.ttl b/tests/int64_arith_test.ttl
new file mode 100644
index 000000000..6cccdac3c
--- /dev/null
+++ b/tests/int64_arith_test.ttl
@@ -0,0 +1,129 @@
+; int64 変数の算術・比較テスト(接続不要)
+;
+; 32ビットを超える値を使って int64 の算術・比較が
+; 正しく動作することを確認する。
+;
+; 使い方: Tera Term マクロとして単体で実行する(接続不要)
+;
+; テスト値:
+; $7FFFFFFF = 2147483647 (32bit int の最大値)
+; $80000000 = 2147483648 (32bit では負になるが int64 では正)
+; $100000000 = 4294967296 (32bit では表現不可)
+
+int64 a
+int64 b
+int64 r
+
+; === 加算 ===
+; 2147483647 + 1 = 2147483648 (32bit ではオーバーフロー)
+a = $7FFFFFFF
+b = 1
+r = a + b
+if r <> $80000000 then
+ messagebox 'NG: 加算エラー ($7FFFFFFF + 1)' 'int64 test'
+ end
+endif
+
+; 2147483648 + 2147483648 = 4294967296
+a = $80000000
+b = $80000000
+r = a + b
+if r <> $100000000 then
+ messagebox 'NG: 加算エラー ($80000000 + $80000000)' 'int64 test'
+ end
+endif
+
+; === 減算 ===
+; 2147483648 - 1 = 2147483647
+a = $80000000
+b = 1
+r = a - b
+if r <> $7FFFFFFF then
+ messagebox 'NG: 減算エラー ($80000000 - 1)' 'int64 test'
+ end
+endif
+
+; 4294967296 - 4294967295 = 1
+a = $100000000
+b = $FFFFFFFF
+r = a - b
+if r <> 1 then
+ messagebox 'NG: 減算エラー ($100000000 - $FFFFFFFF)' 'int64 test'
+ end
+endif
+
+; === 乗算 ===
+; 100000 * 100000 = 10000000000 (> 2^32)
+a = 100000
+b = 100000
+r = a * b
+if r <> 10000000000 then
+ messagebox 'NG: 乗算エラー (100000 * 100000)' 'int64 test'
+ end
+endif
+
+; === 除算 ===
+; 10000000000 / 100000 = 100000
+a = 10000000000
+b = 100000
+r = a / b
+if r <> 100000 then
+ messagebox 'NG: 除算エラー (10000000000 / 100000)' 'int64 test'
+ end
+endif
+
+; === 剰余 ===
+; 10000000001 % 100000 = 1
+a = 10000000001
+b = 100000
+r = a % b
+if r <> 1 then
+ messagebox 'NG: 剰余エラー (10000000001 mod 100000)' 'int64 test'
+ end
+endif
+
+; === 比較: < ===
+a = $7FFFFFFF
+b = $80000000
+if a >= b then
+ messagebox 'NG: 比較エラー ($7FFFFFFF < $80000000)' 'int64 test'
+ end
+endif
+
+; === 比較: > ===
+if b <= a then
+ messagebox 'NG: 比較エラー ($80000000 > $7FFFFFFF)' 'int64 test'
+ end
+endif
+
+; === 比較: <= ===
+a = $80000000
+b = $80000000
+if a > b then
+ messagebox 'NG: 比較エラー ($80000000 <= $80000000)' 'int64 test'
+ end
+endif
+
+; === 比較: >= ===
+if a < b then
+ messagebox 'NG: 比較エラー ($80000000 >= $80000000)' 'int64 test'
+ end
+endif
+
+; === 比較: == ===
+if a <> b then
+ messagebox 'NG: 比較エラー ($80000000 == $80000000)' 'int64 test'
+ end
+endif
+
+; === 比較: <> ===
+a = $7FFFFFFF
+b = $80000000
+if a == b then
+ messagebox 'NG: 比較エラー ($7FFFFFFF <> $80000000)' 'int64 test'
+ end
+endif
+
+messagebox 'OK: int64 算術・比較 全テスト合格' 'int64 test'
+
+end
From 761ffa95cb1b6f178e333bab3e707a22258b43c4 Mon Sep 17 00:00:00 2001
From: Masaru Tsuchiyama
Date: Thu, 4 Jun 2026 15:38:14 +0900
Subject: [PATCH 11/17] Add uptime64 command documentation and tests
- Introduced new HTML documentation for the uptime64 command in both English and Japanese, detailing its usage and providing examples.
- Updated the Tera Term Help Contents (HHC) files to include references to the new uptime64 command.
- Added a test script for uptime64 to verify its functionality without requiring a connection.
This enhances the usability and accessibility of the uptime64 command for users.
---
doc/en/html/macro/command/uptime64.html | 68 +++++++++++++++++++++++++
doc/en/teraterm.hhc | 5 ++
doc/ja/html/macro/command/uptime64.html | 67 ++++++++++++++++++++++++
doc/ja/teraterm.hhc | 5 ++
tests/uptime64.ttl | 20 ++++++++
5 files changed, 165 insertions(+)
create mode 100644 doc/en/html/macro/command/uptime64.html
create mode 100644 doc/ja/html/macro/command/uptime64.html
create mode 100644 tests/uptime64.ttl
diff --git a/doc/en/html/macro/command/uptime64.html b/doc/en/html/macro/command/uptime64.html
new file mode 100644
index 000000000..3b788f136
--- /dev/null
+++ b/doc/en/html/macro/command/uptime64.html
@@ -0,0 +1,68 @@
+
+
+
+
+ uptime
+
+
+
+
+
+
+
+
uptime
+
+
+Gets System Up Time. (version 5.7.0 or later)
+
+
+
+uptime <intvar>
+
+
+
Remarks
+
+
+Retrieves the number of milliseconds that have elapsed since the Windows OS was started,
+and then stores the value into the <int64var> variable.
+
+
+
+The time is valid after the system is run continuously for 49.7 days.
+
+
+
+
Example
+
+
+; How to get the uptime in Windows
+int64 var
+uptime64 var
+day = var / 86400000
+var = var % 86400000
+hour = var / 3600000
+var = var % 3600000
+min = var / 60000
+var = var % 60000
+sec = var / 1000
+
+sprintf2 str "System Up Time: %d Days, %d Hours, %d Minutes, %d Seconds" day hour min sec
+messagebox str "uptime"
+
From fdc9f39bd0f0cadce3cba65736d7a1c31b6aa588 Mon Sep 17 00:00:00 2001
From: Masaru Tsuchiyama
Date: Thu, 4 Jun 2026 16:38:53 +0900
Subject: [PATCH 16/17] Update macro syntax for uptime64 command in English and
Japanese documentation
- Changed 'int64 var' to 'int64 <var>' in both English and Japanese HTML documentation files to improve clarity and accuracy in the usage of the uptime64 command.
- This update ensures that users have the correct syntax for the command.
---
doc/en/html/macro/command/uptime64.html | 2 +-
doc/ja/html/macro/command/uptime64.html | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/doc/en/html/macro/command/uptime64.html b/doc/en/html/macro/command/uptime64.html
index 94585de69..06a900d5f 100644
--- a/doc/en/html/macro/command/uptime64.html
+++ b/doc/en/html/macro/command/uptime64.html
@@ -18,7 +18,7 @@