|
|
@ -1,3 +1,5 @@ |
|
|
|
;; This file is somewhat misnamed. It handles taking categorized entries and processing them into a |
|
|
|
;; format which can be exported. It also helps in cases where pure entries are desired |
|
|
|
(import "FileHelper.cake" "FileSystem.cake" |
|
|
|
"Dictionary.cake" "DynamicArray.cake" |
|
|
|
"Utilities.cake" |
|
|
@ -51,34 +53,43 @@ |
|
|
|
category category-key |
|
|
|
file-handle (* FILE)) |
|
|
|
|
|
|
|
;; Note: entry is not guaranteed to be valid after this call! |
|
|
|
;; Pure meaning, no children have different categories than the current entry |
|
|
|
(defun-local export-write-pure-entry (category-out-files (* category-file-pair) |
|
|
|
num-out-files size_t |
|
|
|
categories (* category-spec) |
|
|
|
entry (* directory-entry-userdata)) |
|
|
|
(each-in-range num-out-files i |
|
|
|
(when (= (path entry > category) (field (at i category-out-files) category)) |
|
|
|
(var out-file (* FILE) (field (at i category-out-files) file-handle)) |
|
|
|
(def-function-signature export-on-pure-entry (categories (* category-spec) |
|
|
|
entry (* directory-entry-userdata) |
|
|
|
userdata (* void))) |
|
|
|
|
|
|
|
(defstruct-local export-write-pure-entry-userdata |
|
|
|
category-out-files (* category-file-pair) |
|
|
|
num-out-files size_t) |
|
|
|
|
|
|
|
(defun-local export-write-pure-entry (categories (* category-spec) |
|
|
|
entry (* directory-entry-userdata) |
|
|
|
userdata-void (* void)) |
|
|
|
(var-cast-to userdata (* export-write-pure-entry-userdata) userdata-void) |
|
|
|
(each-in-range (path userdata > num-out-files) i |
|
|
|
(when (= (path entry > category) (field (at i (path userdata > category-out-files)) category)) |
|
|
|
(var out-file (* FILE) (field (at i (path userdata > category-out-files)) file-handle)) |
|
|
|
(unless out-file |
|
|
|
(fprintf stderr "warning: Could not output: [%s] %s\n" |
|
|
|
(path (dict-ptr-at categories (path entry > category)) > name) |
|
|
|
(path entry > key)) |
|
|
|
(return)) |
|
|
|
(fprintf out-file |
|
|
|
"%s\n" (path entry > key)) |
|
|
|
"%s\n" (path entry > key)) |
|
|
|
(return))) |
|
|
|
;; Category file wasn't open/didn't match, or we were mistakenly passed an uncategorized entry |
|
|
|
(assert 0)) |
|
|
|
|
|
|
|
(defun-local export-category-paths-recursive (sorted-entries (* directory-entry-userdata) ;; dynarray |
|
|
|
categories (* category-spec) ;; dictionary |
|
|
|
current-entry (* directory-entry-userdata) |
|
|
|
entry-index-in-sorted-entries int |
|
|
|
;; When to stop scanning because it's guaranteed there are |
|
|
|
;; no children of the given entry |
|
|
|
upper-bound-for-possible-child-entry int |
|
|
|
category-out-files (* category-file-pair) |
|
|
|
num-out-files size_t) |
|
|
|
(defun-local get-pure-category-paths-recursive (sorted-entries (* directory-entry-userdata) ;; dynarray |
|
|
|
categories (* category-spec) ;; dictionary |
|
|
|
current-entry (* directory-entry-userdata) |
|
|
|
entry-index-in-sorted-entries int |
|
|
|
;; When to stop scanning because it's guaranteed there are |
|
|
|
;; no children of the given entry |
|
|
|
upper-bound-for-possible-child-entry int |
|
|
|
on-pure-entry export-on-pure-entry |
|
|
|
on-pure-entry-userdata (* void)) |
|
|
|
(var num-entries (unsigned int) (dynarray-length sorted-entries)) |
|
|
|
|
|
|
|
;; Determine whether this entry can be directly exported or if it has children with different |
|
|
@ -101,7 +112,7 @@ |
|
|
|
;; No child overrides and we do have a category; safe to export! |
|
|
|
(when (and (not children-override-category) |
|
|
|
(path current-entry > category)) |
|
|
|
(export-write-pure-entry category-out-files num-out-files categories current-entry) |
|
|
|
(on-pure-entry categories current-entry on-pure-entry-userdata) |
|
|
|
(return)) |
|
|
|
|
|
|
|
;; Children do override. More work is needed |
|
|
@ -155,11 +166,11 @@ |
|
|
|
(var scanning-upper-bound int (find-entry-list-scanning-upper-bound sorted-entries |
|
|
|
(path current-entry > key) |
|
|
|
entry-index-in-sorted-entries)) |
|
|
|
(export-category-paths-recursive |
|
|
|
(get-pure-category-paths-recursive |
|
|
|
sorted-entries categories |
|
|
|
(addr auto-child-entry) earliest-possible-relevant-entry |
|
|
|
scanning-upper-bound |
|
|
|
category-out-files num-out-files)) |
|
|
|
on-pure-entry on-pure-entry-userdata)) |
|
|
|
(dynarray-free entry-child-path) |
|
|
|
(directory-entries-destroy child-entries) |
|
|
|
(set child-entries null)) |
|
|
@ -176,9 +187,11 @@ |
|
|
|
(scope |
|
|
|
(set num-out-files (dict-length categories)) |
|
|
|
(dynarray-set-length category-out-files num-out-files) |
|
|
|
(memset category-out-files 0 (dynarray-length-sizeof category-out-files)) |
|
|
|
(var category-file-name dynstring null) |
|
|
|
(dynarray-set-capacity category-file-name 32) |
|
|
|
(each-item-in-dict categories i category (* category-spec) |
|
|
|
(when (path category > is-deleted) (continue)) |
|
|
|
(dynarray-clear category-file-name) |
|
|
|
(each-char-in-string-const (path category > name) c |
|
|
|
(var forbidden-characters (* (const char)) "<>:\"/\\|?*") |
|
|
@ -221,7 +234,7 @@ |
|
|
|
(var previous-sibling-entry (* directory-entry-userdata) null) |
|
|
|
(each-item-addr-in-dynarray sorted-entries i entry (* directory-entry-userdata) |
|
|
|
;; The recursive scanning nature of this algorithm means that a directory will handle all of |
|
|
|
;; the subsequent children in export-category-paths-recursive, so skip over them here |
|
|
|
;; the subsequent children in get-pure-category-paths-recursive, so skip over them here |
|
|
|
(when previous-sibling-entry |
|
|
|
(var previous-path-length size_t (strlen (path previous-sibling-entry > key))) |
|
|
|
(when (is-child-or-match-of-path (path previous-sibling-entry > key) |
|
|
@ -231,9 +244,11 @@ |
|
|
|
(var scan-list-upper-bound int (find-entry-list-scanning-upper-bound |
|
|
|
;; Start one entry ahead because we know we're exactly on it |
|
|
|
sorted-entries (path entry > key) (+ 1 i))) |
|
|
|
(export-category-paths-recursive sorted-entries categories |
|
|
|
entry (+ 1 i) scan-list-upper-bound |
|
|
|
category-out-files num-out-files) |
|
|
|
(var write-pure-entry-userdata export-write-pure-entry-userdata |
|
|
|
(array category-out-files num-out-files)) |
|
|
|
(get-pure-category-paths-recursive sorted-entries categories |
|
|
|
entry (+ 1 i) scan-list-upper-bound |
|
|
|
export-write-pure-entry (addr write-pure-entry-userdata)) |
|
|
|
(set previous-sibling-entry entry)) |
|
|
|
|
|
|
|
(each-item-addr-in-dynarray category-out-files i category-file (* category-file-pair) |
|
|
|