// Copyright (c) 2026 Charles KWON OhJun (charleskwonohjun@gmail.com) // All rights reserved. // Missing RTL functions needed by FiveSql2 and other Harbour programs. package hbrtl import ( "five/hbrt" "os" "strings" ) // hb_FileExists(cFile) → lExists func HbFileExists(t *hbrt.Thread) { t.Frame(1, 0) defer t.EndProcFast() fname := t.Local(1).AsString() _, err := os.Stat(fname) t.PushBool(err == nil) t.RetValue() } // hb_Second(dTimestamp) → nSeconds (seconds portion of timestamp) func HbSecond(t *hbrt.Thread) { t.Frame(1, 0) defer t.EndProcFast() v := t.Local(1) if v.IsTimestamp() { ms := v.AsTimeMs() secs := int64(ms/1000) % 60 t.RetInt(secs) } else { t.RetInt(0) } } // hb_ATokens(cString [, cDelim]) → aTokens // Splits string by delimiter (default: space/tab/newline) func HbATokens(t *hbrt.Thread) { nParams := t.ParamCount() t.Frame(nParams, 0) defer t.EndProcFast() s := t.Local(1).AsString() delim := " " if nParams >= 2 && !t.Local(2).IsNil() { delim = t.Local(2).AsString() } var parts []string if delim == " " { parts = strings.Fields(s) } else { parts = strings.Split(s, delim) } items := make([]hbrt.Value, len(parts)) for i, p := range parts { items[i] = hbrt.MakeString(p) } t.PushValue(hbrt.MakeArrayFrom(items)) t.RetValue() } // hb_cdpSelect([cCodepage]) → cPrevCodepage // Stub: Five uses UTF-8 internally, codepage selection is a no-op. func HbCdpSelect(t *hbrt.Thread) { nParams := t.ParamCount() t.Frame(nParams, 0) defer t.EndProcFast() t.RetString("") } // Used() → lUsed — checks if current workarea is in use func Used(t *hbrt.Thread) { t.Frame(0, 0) defer t.EndProcFast() wam := getWA(t) if wam == nil { t.RetBool(false) return } t.RetBool(wam.Current() != nil) } // DBSETINDEX — SET INDEX TO (adds index to current workarea) func rtlDbSetIndex(t *hbrt.Thread) { nParams := t.ParamCount() t.Frame(nParams, 0) defer t.EndProcFast() // Delegate to the SET INDEX TO handler in the RDD layer // For now, this is handled by the generated code's SET INDEX TO command. t.RetNil() }