This commit is contained in:
Raven Scott
2026-04-03 21:39:36 -04:00
parent 2655fe6a7d
commit 57b1296981
355 changed files with 781062 additions and 7351 deletions
@@ -0,0 +1,336 @@
/**
* GNU-style LS_COLORS string + dircolors(5) database parsing and file classification.
* Consumed by bare-os-booter (ESM import). Prepended into /bin/ls and /bin/dircolors by bare-os-coreutils build (no import there).
*/
/** Default LS_COLORS (subset aligned with GNU dircolors -p essentials + common globs). */
function bareDefaultLsColorsString() {
return [
'no=00',
'fi=00',
'di=01;34',
'ln=01;36',
'pi=40;33',
'so=01;35',
'do=01;35',
'bd=40;33;01',
'cd=40;33;01',
'or=40;31;01',
'mi=00',
'su=37;41',
'sg=30;43',
'ca=30;41',
'tw=30;42',
'ow=34;43',
'st=37;44',
'ex=01;32',
'mh=00',
'*.tar=01;31',
'*.tgz=01;31',
'*.arc=01;31',
'*.arj=01;31',
'*.taz=01;31',
'*.lha=01;31',
'*.lz4=01;31',
'*.lzh=01;31',
'*.tlz=01;31',
'*.txz=01;31',
'*.tzo=01;31',
'*.tzst=01;31',
'*.bz2=01;31',
'*.bz=01;31',
'*.tbz=01;31',
'*.tbz2=01;31',
'*.tz=01;31',
'*.deb=01;31',
'*.rpm=01;31',
'*.jar=01;31',
'*.war=01;31',
'*.ear=01;31',
'*.sar=01;31',
'*.rar=01;31',
'*.alz=01;31',
'*.ace=01;31',
'*.zoo=01;31',
'*.cpio=01;31',
'*.7z=01;31',
'*.rz=01;31',
'*.cab=01;31',
'*.wim=01;31',
'*.swm=01;31',
'*.dwm=01;31',
'*.esd=01;31',
'*.jpg=01;35',
'*.jpeg=01;35',
'*.mjpg=01;35',
'*.mjpeg=01;35',
'*.gif=01;35',
'*.bmp=01;35',
'*.pbm=01;35',
'*.pgm=01;35',
'*.ppm=01;35',
'*.tga=01;35',
'*.xbm=01;35',
'*.xpm=01;35',
'*.tif=01;35',
'*.tiff=01;35',
'*.png=01;35',
'*.svg=01;35',
'*.svgz=01;35',
'*.mng=01;35',
'*.pcx=01;35',
'*.mov=01;35',
'*.mpg=01;35',
'*.mpeg=01;35',
'*.m2v=01;35',
'*.mkv=01;35',
'*.webm=01;35',
'*.ogm=01;35',
'*.mp4=01;35',
'*.m4v=01;35',
'*.mp4v=01;35',
'*.vob=01;35',
'*.qt=01;35',
'*.nuv=01;35',
'*.wmv=01;35',
'*.asf=01;35',
'*.rm=01;35',
'*.rmvb=01;35',
'*.flc=01;35',
'*.avi=01;35',
'*.fli=01;35',
'*.flv=01;35',
'*.gl=01;35',
'*.dl=01;35',
'*.xcf=01;35',
'*.xwd=01;35',
'*.yuv=01;35',
'*.cgm=01;35',
'*.emf=01;35',
'*.ogv=01;35',
'*.ogx=01;35',
'*.aac=00;36',
'*.au=00;36',
'*.flac=00;36',
'*.m4a=00;36',
'*.mid=00;36',
'*.midi=00;36',
'*.mka=00;36',
'*.mp3=00;36',
'*.mpc=00;36',
'*.ogg=00;36',
'*.ra=00;36',
'*.wav=00;36',
'*.oga=00;36',
'*.opus=00;36',
'*.spx=00;36',
'*.xspf=00;36',
'*.pdf=00;32',
'*.ps=00;32',
'*.txt=00;32',
'*.patch=00;32',
'*.diff=00;32',
'*.log=00;32',
'*.tex=00;32',
'*.doc=00;32',
'*.docx=00;32',
'*.rtf=00;32',
'*.odt=00;32',
'*.md=00;32',
'*.markdown=00;32',
'*.css=00;32',
'*.htm=00;32',
'*.html=00;32',
'*.xml=00;32',
'*.json=00;32',
'*.yaml=00;32',
'*.yml=00;32',
'*.c=00;32',
'*.h=00;32',
'*.js=00;32',
'*.mjs=00;32',
'*.java=00;32',
'*.py=00;32',
'*.go=00;32',
'*.rs=00;32',
'*.cpp=00;32',
'*.cc=00;32',
'*.cxx=00;32',
'*.hpp=00;32',
'*.shlib=01;32',
'*.so=01;32',
'*.dylib=01;32',
'*.dll=01;32',
'*.a=01;32',
'*.lib=01;32',
'*.ko=01;32',
'*.sh=01;32',
'*.bash=01;32',
'*.zsh=01;32',
'*.bat=01;32',
'*.cmd=01;32',
'*.exe=01;32',
'*.com=01;32',
'*.btm=01;32',
'*.msi=01;32'
].join(':')
}
/**
* @param {string} s
* @returns {Record<string, string>}
*/
function bareParseLsColors(s) {
const out = /** @type {Record<string, string>} */ ({})
if (s == null || !String(s).trim()) return out
for (const part of String(s).split(':')) {
const p = part.trim()
if (!p) continue
const eq = p.indexOf('=')
if (eq <= 0) continue
const k = p.slice(0, eq)
const v = p.slice(eq + 1)
if (k) out[k] = v
}
return out
}
/**
* @param {Record<string, string>} map
*/
function bareSerializeLsColors(map) {
const keys = Object.keys(map).sort()
return keys.map((k) => k + '=' + map[k]).join(':')
}
/**
* @param {string} code dircolors value (e.g. 01;34)
* @returns {string} opening SGR including ESC
*/
function bareLscolorsToOpenSgr(code) {
if (code == null || code === '' || code === '0' || code === '00') return ''
return '\x1b[' + code + 'm'
}
/**
* Parse dircolors database (GNU subset): # comments, blank lines, TERM blocks, KEY VALUE pairs.
* @param {string} text
* @param {string} termEnv value of TERM
* @returns {Record<string, string>}
*/
function bareParseDircolorsDatabase(text, termEnv) {
const term = termEnv != null ? String(termEnv) : ''
/** @type {Record<string, string>} */
const out = {}
let blockActive = true
const lines = String(text).split(/\r?\n/)
for (let raw of lines) {
const line = raw.replace(/#.*$/, '').trim()
if (!line) continue
const upper = line.toUpperCase()
if (upper.startsWith('TERM ')) {
const rest = line.slice(5).trim()
if (rest === 'none') blockActive = false
else
blockActive =
rest === '*' || rest === '' || rest === term || term.indexOf(rest) === 0
continue
}
if (upper.startsWith('COLOR ') || upper.startsWith('OPTIONS ')) continue
if (!blockActive) continue
const ws = line.search(/\s/)
if (ws <= 0) continue
const key = line.slice(0, ws).trim()
const val = line.slice(ws + 1).trim()
if (!key || !val) continue
if (key === 'TERM' || key === 'COLOR' || key === 'OPTIONS') continue
out[key] = val
}
return out
}
/**
* @param {string} filename basename only
* @param {Record<string, string>} map
*/
function bareLsColorsGlobMatch(filename, map) {
const keys = Object.keys(map).filter((k) => k.startsWith('*.'))
keys.sort((a, b) => b.length - a.length)
const lower = filename.toLowerCase()
for (const k of keys) {
const suf = k.slice(1).toLowerCase()
if (lower.endsWith(suf)) return map[k]
}
return null
}
/**
* @param {{ type?: string, mode?: number, linkname?: string, targetMissing?: boolean, nlink?: number, capabilities?: boolean } | null} st
* @param {string} filename basename
* @param {Record<string, string>} map from LS_COLORS
* @returns {string} SGR open sequence or ''
*/
function bareLsColorOpenSgrFromMap(st, filename, map) {
if (!st) {
const no = map.no
return no ? bareLscolorsToOpenSgr(no) : ''
}
const mode = Number(st.mode) || 0
const perm = mode & 0o777
const t = st.type
let key = 'fi'
if (t === 'symlink') {
key = st.targetMissing ? 'or' : 'ln'
} else if (t === 'directory') {
const ow = (perm & 0o002) !== 0
const sticky = (mode & 0o1000) !== 0
if (ow && sticky) key = 'tw'
else if (ow) key = 'ow'
else if (sticky) key = 'st'
else key = 'di'
} else if (t === 'file') {
if (st.capabilities) key = 'ca'
else if (mode & 0o4000) key = 'su'
else if (mode & 0o2000) key = 'sg'
else if (perm & 0o111) key = 'ex'
else {
const nlink = Number(st.nlink)
if (nlink > 1 && map.mh != null && String(map.mh).trim() !== '') {
const mhOpen = bareLscolorsToOpenSgr(map.mh)
if (mhOpen) return mhOpen
}
const g = bareLsColorsGlobMatch(filename, map)
if (g != null) return bareLscolorsToOpenSgr(g)
key = 'fi'
}
}
const code = map[key] != null ? map[key] : map.fi
return code ? bareLscolorsToOpenSgr(code) : ''
}
/**
* @returns {string} multiline dircolors database (default colors)
*/
function bareDefaultDircolorsDatabase() {
const pairs = bareParseLsColors(bareDefaultLsColorsString())
const lines = ['# Bare OS default dircolors (GNU-like)', 'TERM *', '']
for (const k of Object.keys(pairs).sort()) {
lines.push(k + ' ' + pairs[k])
}
return lines.join('\n') + '\n'
}
// BARE_OS_LSCOLORS_BUNDLE_END (lines below are stripped when embedding in /bin/*)
export {
bareDefaultLsColorsString,
bareParseLsColors,
bareSerializeLsColors,
bareLscolorsToOpenSgr,
bareParseDircolorsDatabase,
bareLsColorsGlobMatch,
bareLsColorOpenSgrFromMap,
bareDefaultDircolorsDatabase
}