*! _gvar_engine 1.0.1 21aug2026 *! Loads and verifies the Mata computational engine of the gvar package. *! Author: Merwan Roudane *! merwanroudane920@gmail.com *! https://github.com/merwanroudane * * The whole engine lives in _gvar_mata.ado as a single mata: block, so that * `struct gvarmodel' is always compiled before the routines that use it. * * The file is sourced with -run- (not by invoking a program) because -run- * executes it top to bottom exactly like -do-, which is the only mechanism * that reliably compiles a mata: block held inside an ado-file. program define _gvar_engine version 14.0 * ----------------------------------------------------------------------- * 1. Shared helper programs (_gvar_title, _gvar_palette, _gvar_require...) * ----------------------------------------------------------------------- * They live together in _gvar_util.ado. Stata only auto-loads an ado-file * whose NAME matches the command being called, so a helper defined inside * a differently-named file is never found on its own; the file has to be * sourced explicitly. capture _gvar_palette if (_rc) { capture findfile _gvar_util.ado if (_rc) { di as err "gvar: cannot locate {bf:_gvar_util.ado} on the adopath" exit 601 } quietly run `"`r(fn)'"' } capture _gvar_palette if (_rc) { di as err "gvar: the shared helper programs failed to load" exit 499 } * ----------------------------------------------------------------------- * 2. The Mata engine * ----------------------------------------------------------------------- * The engine is reloaded unless the COMPILED version is the one this file * expects. Testing only that gvar_version() resolves was wrong: Mata * functions survive -discard-, so a user who ran -ssc install gvar, replace- * mid-session kept executing the previous engine against the new ado files, * silently, for the rest of the session. Comparing versions costs one Mata * call and makes an in-session upgrade take effect. local gvarexpect 1.0.1 capture mata: st_local("__gvarver", gvar_version()) if (_rc == 0 & "`__gvarver'" == "`gvarexpect'") { exit } if (_rc == 0 & "`__gvarver'" != "") { * A DIFFERENT engine is compiled -- the ado files have been upgraded * under a session that still holds the old Mata code. Mata refuses to * redefine an existing function ("gvar_version() already exists", * r(3000)), so the old one has to go before the new file is run. The * drop is scoped to gvar_*(): -mata clear- would work too but would * destroy whatever Mata functions and objects the USER has defined, * which is not this package's to throw away. * Say what is about to be lost. Replacing the engine drops gvar_MODEL * along with the struct it is an instance of, so any fitted model goes * with it -- the alternative, keeping a stale engine, means running new * ado files against old Mata code and getting wrong answers quietly. * Without this message the user sees only "no GVAR in memory" from the * NEXT command and has no idea why. di as text "{p}gvar: the compiled Mata engine is version " /// as result "`__gvarver'" as text " but these ado files are " /// as result "`gvarexpect'" as text " -- the package was upgraded " /// "during this session. Reloading the engine now. Any model in " /// "memory is discarded with it, so re-run {bf:gvar setup} and the " /// "steps after it.{p_end}" * Everything the engine defines, in dependency order: the functions * first, then the model object, then the struct it is an instance of. * gvarmodel does NOT match gvar_* -- it has no underscore -- and six * routines carry the _gvar_ prefix, so a single gvar_*() drop leaves * both behind and the recompile dies "gvarmodel() already exists". capture mata: mata drop gvar_*() capture mata: mata drop _gvar_*() capture mata: mata drop gvar_MODEL capture mata: mata drop gvarmodel() } capture findfile _gvar_mata.ado if (_rc) { di as err "gvar: cannot locate {bf:_gvar_mata.ado} on the adopath" di as err "the gvar package looks incompletely installed" exit 601 } local mfile `"`r(fn)'"' quietly run `"`mfile'"' capture mata: st_local("__gvarver", gvar_version()) if (_rc | "`__gvarver'" == "") { di as err "gvar: the Mata engine failed to compile" di as err `"run {bf:do "`mfile'"} directly to see the offending line"' exit 499 } end