|
31 | 31 | local link_refs = {} |
32 | 32 | local types_dir, output_dir |
33 | 33 |
|
| 34 | +local has_ffi, ffi = pcall(require, "ffi") |
| 35 | +if has_ffi then |
| 36 | + ffi.cdef [[ |
| 37 | + int access(const char *pathname, int mode); |
| 38 | + int mkdir(const char *pathname, unsigned int mode); |
| 39 | + ]] |
| 40 | +end |
| 41 | + |
34 | 42 | local function shell_quote(s) |
35 | 43 | return "'" .. tostring(s):gsub("'", [['"'"']]) .. "'" |
36 | 44 | end |
37 | 45 |
|
38 | 46 | local function exists_dir(path) |
39 | | - local ok = os.execute("[ -d " .. shell_quote(path) .. " ]") |
40 | | - return ok == true or ok == 0 |
| 47 | + if has_ffi then |
| 48 | + return ffi.C.access(path .. "/.", 0) == 0 |
| 49 | + else |
| 50 | + local f = io.open(path .. "/.", "r") |
| 51 | + if f then |
| 52 | + f:close() |
| 53 | + return true |
| 54 | + end |
| 55 | + return false |
| 56 | + end |
41 | 57 | end |
42 | 58 |
|
43 | 59 | local function is_valid_module(module) |
44 | | - if not module then return false end |
| 60 | + if not module then |
| 61 | + return false |
| 62 | + end |
45 | 63 | local std_types = { |
46 | | - string = true, number = true, boolean = true, table = true, |
47 | | - ["function"] = true, thread = true, userdata = true, ["nil"] = true, |
48 | | - any = true, void = true, integer = true, unknown = true |
| 64 | + string = true, |
| 65 | + number = true, |
| 66 | + boolean = true, |
| 67 | + table = true, |
| 68 | + ["function"] = true, |
| 69 | + thread = true, |
| 70 | + userdata = true, |
| 71 | + ["nil"] = true, |
| 72 | + any = true, |
| 73 | + void = true, |
| 74 | + integer = true, |
| 75 | + unknown = true, |
49 | 76 | } |
50 | | - if std_types[module] then return false end |
| 77 | + if std_types[module] then |
| 78 | + return false |
| 79 | + end |
51 | 80 | local path = script_dir .. "/../docs/src/" .. module |
52 | 81 | return exists_dir(path) |
53 | 82 | end |
@@ -574,10 +603,23 @@ end |
574 | 603 | -- File System / CLI Helpers |
575 | 604 | -- ========================================================================= |
576 | 605 |
|
577 | | - |
578 | | - |
579 | 606 | local function mkdir_p(path) |
580 | | - assert(os.execute("mkdir -p " .. shell_quote(path))) |
| 607 | + if has_ffi then |
| 608 | + local current = "" |
| 609 | + if path:sub(1, 1) == "/" then |
| 610 | + current = "/" |
| 611 | + end |
| 612 | + for part in path:gmatch("[^/]+") do |
| 613 | + if current == "/" or current == "" then |
| 614 | + current = current .. part |
| 615 | + else |
| 616 | + current = current .. "/" .. part |
| 617 | + end |
| 618 | + ffi.C.mkdir(current, 493) -- 0755 permissions |
| 619 | + end |
| 620 | + else |
| 621 | + os.execute("mkdir -p " .. shell_quote(path)) |
| 622 | + end |
581 | 623 | end |
582 | 624 |
|
583 | 625 | local function read_file(path) |
@@ -1408,7 +1450,9 @@ local function split_top_level_unions(s) |
1408 | 1450 | depth = depth + 1 |
1409 | 1451 | insert(current, char) |
1410 | 1452 | elseif char == ")" or char == "}" or char == ">" then |
1411 | | - if depth > 0 then depth = depth - 1 end |
| 1453 | + if depth > 0 then |
| 1454 | + depth = depth - 1 |
| 1455 | + end |
1412 | 1456 | insert(current, char) |
1413 | 1457 | elseif char == "|" and depth == 0 then |
1414 | 1458 | insert(parts, table.concat(current)) |
@@ -1508,13 +1552,27 @@ local function generate_alias_docs(types_dir, output_dir) |
1508 | 1552 | item.filename = filename |
1509 | 1553 | if (item.kind == "alias" and not is_function_doc_item(item)) or item.kind == "enum" then |
1510 | 1554 | local alias_name = (item.name or ""):gsub("<[^>]+>", "") |
1511 | | - if alias_name ~= "" and alias_name ~= "_" and alias_name ~= "M" and not alias_name:match("^M%.") and alias_name ~= "_G" and not alias_name:match("^_G%.") then |
| 1555 | + if |
| 1556 | + alias_name ~= "" |
| 1557 | + and alias_name ~= "_" |
| 1558 | + and alias_name ~= "M" |
| 1559 | + and not alias_name:match("^M%.") |
| 1560 | + and alias_name ~= "_G" |
| 1561 | + and not alias_name:match("^_G%.") |
| 1562 | + then |
1512 | 1563 | insert(aliases, item) |
1513 | 1564 | end |
1514 | 1565 | elseif item.kind == "class" then |
1515 | 1566 | local class_name = item.view:match("^([^:]+)") or item.view |
1516 | 1567 | class_name = trim(class_name):gsub("<[^>]+>", "") |
1517 | | - if class_name ~= "" and class_name ~= "_" and class_name ~= "M" and not class_name:match("^M%.") and class_name ~= "_G" and not class_name:match("^_G%.") then |
| 1568 | + if |
| 1569 | + class_name ~= "" |
| 1570 | + and class_name ~= "_" |
| 1571 | + and class_name ~= "M" |
| 1572 | + and not class_name:match("^M%.") |
| 1573 | + and class_name ~= "_G" |
| 1574 | + and not class_name:match("^_G%.") |
| 1575 | + then |
1518 | 1576 | insert(classes, item) |
1519 | 1577 | end |
1520 | 1578 | elseif item.kind == "function" or (item.kind == "alias" and is_function_doc_item(item)) then |
@@ -1829,11 +1887,7 @@ local function generate_alias_docs(types_dir, output_dir) |
1829 | 1887 | for _, field in ipairs(processed) do |
1830 | 1888 | insert( |
1831 | 1889 | detail, |
1832 | | - string.format( |
1833 | | - "`%s` | %s", |
1834 | | - field.display_key, |
1835 | | - esc_table_cell(format_type_value_inline(field.type)) |
1836 | | - ) |
| 1890 | + string.format("`%s` | %s", field.display_key, esc_table_cell(format_type_value_inline(field.type))) |
1837 | 1891 | ) |
1838 | 1892 | end |
1839 | 1893 | end |
|
0 commit comments