// Copyright (c) 2026 Charles KWON OhJun (charleskwonohjun@gmail.com) // All rights reserved. // SET command functions: SET EXACT, SET SOFTSEEK, SET DELETED, SET EXCLUSIVE, // SET(_SET_xxx, lValue) pattern. // Harbour: src/rtl/set.c — 47+ settings in HB_SET_ENUM. package hbrtl import ( "five/hbrdd" "five/hbrt" "sync" ) // SET indices (Harbour HB_SET_ENUM compatible) const ( SetExact = 1 SetFixed = 2 SetDecimals = 3 SetDateFmt = 4 SetEpoch = 5 SetPath = 6 SetDefault = 7 SetDeleted = 8 SetExclusive = 11 SetSoftSeek = 12 SetUnique = 13 SetCancel = 14 SetConfirm = 15 SetConsole = 16 SetAlternate = 17 SetDevice = 18 SetPrinter = 19 SetBell = 20 SetEscape = 21 SetInsert = 22 SetExit = 23 SetIntensity = 24 SetScoreB = 25 SetColorIdx = 26 SetCursorIdx = 27 SetWrap = 28 SetMessage = 29 ) var ( settings = map[int]hbrt.Value{ SetExact: hbrt.MakeBool(false), SetFixed: hbrt.MakeBool(false), SetDecimals: hbrt.MakeInt(2), SetDeleted: hbrt.MakeBool(false), SetExclusive: hbrt.MakeBool(true), SetSoftSeek: hbrt.MakeBool(false), SetUnique: hbrt.MakeBool(false), SetCancel: hbrt.MakeBool(true), SetConfirm: hbrt.MakeBool(false), SetConsole: hbrt.MakeBool(true), SetBell: hbrt.MakeBool(false), SetEscape: hbrt.MakeBool(true), SetInsert: hbrt.MakeBool(false), SetExit: hbrt.MakeBool(false), SetIntensity: hbrt.MakeBool(true), SetWrap: hbrt.MakeBool(false), } setMu sync.Mutex ) // SET(nSpecifier [, xNewValue]) → xOldValue // Generic SET function matching Harbour's Set() function. func SetFunc(t *hbrt.Thread) { nParams := t.ParamCount() t.Frame(nParams, 0) defer t.EndProc() nSet := t.Local(1).AsInt() setMu.Lock() defer setMu.Unlock() old, exists := settings[nSet] if !exists { old = hbrt.MakeNil() } if nParams >= 2 && !t.Local(2).IsNil() { settings[nSet] = t.Local(2) } t.RetVal(old) } // GetSetting returns a SET value (called internally). func GetSetting(nSet int) hbrt.Value { setMu.Lock() defer setMu.Unlock() v, ok := settings[nSet] if !ok { return hbrt.MakeNil() } return v } // GetSetDeleted returns SET DELETED state. func GetSetDeleted() bool { return GetSetting(SetDeleted).AsBool() } // GetSetExact returns SET EXACT state. func GetSetExact() bool { return GetSetting(SetExact).AsBool() } // GetSetSoftSeek returns SET SOFTSEEK state. func GetSetSoftSeek() bool { return GetSetting(SetSoftSeek).AsBool() } // GetSetDateFormat returns SET DATE format string. func GetSetDateFormat() string { v := GetSetting(SetDateFmt) if v.IsString() { return v.AsString() } return "mm/dd/yy" } // GetSetDecimals returns SET DECIMALS value. func GetSetDecimals() int { return GetSetting(SetDecimals).AsInt() } // GetSetEpoch returns SET EPOCH year. func GetSetEpoch() int { v := GetSetting(SetEpoch) if v.IsNumeric() { return v.AsInt() } return 1900 } // --- Dedicated SET toggle functions --- // Harbour: SET EXACT ON/OFF, SET DELETED ON/OFF, etc. // SetExactFunc: SET(_SET_EXACT [, lNew]) → lOld func SetExactFunc(t *hbrt.Thread) { setToggle(t, SetExact) } // SetDeletedFunc: SET(_SET_DELETED [, lNew]) → lOld func SetDeletedFunc(t *hbrt.Thread) { setToggle(t, SetDeleted) } // SetSoftSeekFunc: SET(_SET_SOFTSEEK [, lNew]) → lOld func SetSoftSeekFunc(t *hbrt.Thread) { setToggle(t, SetSoftSeek) } // SetExclusiveFunc: SET(_SET_EXCLUSIVE [, lNew]) → lOld func SetExclusiveFunc(t *hbrt.Thread) { setToggle(t, SetExclusive) } // SetFixedFunc: SET(_SET_FIXED [, lNew]) → lOld func SetFixedFunc(t *hbrt.Thread) { setToggle(t, SetFixed) } // SetCancelFunc: SET(_SET_CANCEL [, lNew]) → lOld func SetCancelFunc(t *hbrt.Thread) { setToggle(t, SetCancel) } // SetBellFunc: SET(_SET_BELL [, lNew]) → lOld func SetBellFunc(t *hbrt.Thread) { setToggle(t, SetBell) } // SetConfirmFunc: SET(_SET_CONFIRM [, lNew]) → lOld func SetConfirmFunc(t *hbrt.Thread) { setToggle(t, SetConfirm) } // SetInsertFunc: SET(_SET_INSERT [, lNew]) → lOld func SetInsertFunc(t *hbrt.Thread) { setToggle(t, SetInsert) } // SetEscapeFunc: SET(_SET_ESCAPE [, lNew]) → lOld func SetEscapeFunc(t *hbrt.Thread) { setToggle(t, SetEscape) } // SetWrapFunc: SET(_SET_WRAP [, lNew]) → lOld func SetWrapFunc(t *hbrt.Thread) { setToggle(t, SetWrap) } // setToggle implements SET(n, lNew) → lOld for boolean settings func setToggle(t *hbrt.Thread, setID int) { nParams := t.ParamCount() t.Frame(nParams, 0) defer t.EndProc() setMu.Lock() defer setMu.Unlock() old, ok := settings[setID] if !ok { old = hbrt.MakeBool(false) } if nParams >= 1 && !t.Local(1).IsNil() { settings[setID] = t.Local(1) } t.RetVal(old) } // SetDateFunc: __SetDateFormat([cNew]) → cOld func SetDateFunc(t *hbrt.Thread) { nParams := t.ParamCount() t.Frame(nParams, 0) defer t.EndProc() setMu.Lock() defer setMu.Unlock() old, ok := settings[SetDateFmt] if !ok { old = hbrt.MakeString("mm/dd/yy") } if nParams >= 1 && t.Local(1).IsString() { dfmt := t.Local(1).AsString() settings[SetDateFmt] = hbrt.MakeString(dfmt) } t.RetVal(old) } // SetDecimalsFunc: SET DECIMALS TO n func SetDecimalsFunc(t *hbrt.Thread) { nParams := t.ParamCount() t.Frame(nParams, 0) defer t.EndProc() setMu.Lock() defer setMu.Unlock() old := settings[SetDecimals] if nParams >= 1 && t.Local(1).IsNumeric() { settings[SetDecimals] = t.Local(1) } t.RetVal(old) } // SetEpochFunc: SET EPOCH TO n func SetEpochFunc(t *hbrt.Thread) { nParams := t.ParamCount() t.Frame(nParams, 0) defer t.EndProc() setMu.Lock() defer setMu.Unlock() old, ok := settings[SetEpoch] if !ok { old = hbrt.MakeInt(1900) } if nParams >= 1 && t.Local(1).IsNumeric() { settings[SetEpoch] = t.Local(1) } t.RetVal(old) } // --- SET constants for PRG code (registered as RTL functions) --- // _SET_EXACT etc. — return the SET index constant func SetConstExact(t *hbrt.Thread) { t.Frame(0, 0); defer t.EndProc(); t.PushInt(SetExact); t.RetValue() } func SetConstDeleted(t *hbrt.Thread) { t.Frame(0, 0); defer t.EndProc(); t.PushInt(SetDeleted); t.RetValue() } func SetConstSoftSeek(t *hbrt.Thread) { t.Frame(0, 0); defer t.EndProc(); t.PushInt(SetSoftSeek); t.RetValue() } func SetConstExclusive(t *hbrt.Thread) { t.Frame(0, 0); defer t.EndProc(); t.PushInt(SetExclusive); t.RetValue() } func SetConstDateFmt(t *hbrt.Thread) { t.Frame(0, 0); defer t.EndProc(); t.PushInt(SetDateFmt); t.RetValue() } func SetConstDecimals(t *hbrt.Thread) { t.Frame(0, 0); defer t.EndProc(); t.PushInt(SetDecimals); t.RetValue() } func SetConstEpoch(t *hbrt.Thread) { t.Frame(0, 0); defer t.EndProc(); t.PushInt(SetEpoch); t.RetValue() } // init registers default DATE format and EPOCH, and hooks into hbrdd. func init() { hbrdd.IsSetDeleted = GetSetDeleted setMu.Lock() if _, ok := settings[SetDateFmt]; !ok { settings[SetDateFmt] = hbrt.MakeString("mm/dd/yy") } if _, ok := settings[SetEpoch]; !ok { settings[SetEpoch] = hbrt.MakeInt(1900) } setMu.Unlock() }