1- # YT#VHb3a67af97b323ee47762788154a489fd#VHa53bd254d6ac8e6a19dfa057febb06b5 #
1+ # YT#VH20fe8acb2e57832933eb60226847381a#VHe9395a780f86f7653c9f11cadba1e3f0 #
22CM <- local({ # _C_hecked _M_odule
3+ # 2025-07-11: [feature] New `manual_check` flag to tell `CM$generate_check_functions()` to ignore particular elements
4+ # 2025-04-09: [fix] Make `generate_map_afmm_function` maps multi-variable parameters (e.g. `visit_vars`)
35 # 2025-03-21: [feature] report errors for all loaded datasets and [fix] dehardcode "PARAM" string and use `par` argument
46
57 message_well <- function (title , contents , color = " f5f5f5" ) {
@@ -281,6 +283,13 @@ CM <- local({ # _C_hecked _M_odule
281283 elem <- spec $ elements [[elem_name ]]
282284 attrs_ids <- setdiff(names(attributes(elem )), c(" names" , " docs" ))
283285 attrs <- attributes(elem )[attrs_ids ]
286+
287+ if (isTRUE(attrs [[" manual_check" ]])) {
288+ push(sprintf(" 'NOTE: %s (%s) tagged as \" manual_check\" '\n " , elem_name , elem $ kind ))
289+ push(sprintf(" ' The expectation is that it either does not require automated checks or that'\n " ))
290+ push(sprintf(" ' the caller of this function has written manual checks near the call site.'\n " ))
291+ next
292+ }
284293
285294 if (isTRUE(attrs [[" subjid_var" ]])) {
286295 subjid_vars <- c(subjid_vars , elem_name )
@@ -320,6 +329,11 @@ CM <- local({ # _C_hecked _M_odule
320329 " OK[['%s']] <- CM$check_function('%s', %s, %d, flags, warn, err)\n " ,
321330 elem_name , elem_name , elem_name , elem $ arg_count
322331 ))
332+ } else if (elem $ kind == " group" ) {
333+ push(sprintf(" 'NOTE: %s (%s) unsupported as the check generator cannot handle nested elements yet'\n " ,
334+ elem_name , elem $ kind ))
335+ push(sprintf(" ' The expectation is that it either does not require automated checks or that'\n " ))
336+ push(sprintf(" ' the caller of this function has written manual checks near the call site.'\n " ))
323337 } else {
324338 push(sprintf(" 'NOTE: %s (%s) has no associated automated checks'\n " , elem_name , elem $ kind ))
325339 push(sprintf(" ' The expectation is that it either does not require them or that'\n " ))
@@ -422,11 +436,24 @@ CM <- local({ # _C_hecked _M_odule
422436 elem <- spec $ elements [[elem_name ]]
423437 stopifnot(elem $ kind == " col" )
424438 dataset_name <- elem [[" dataset_name" ]]
425- push(sprintf(" if(is.character(ds[[%s]][[%s]])){\n " , dataset_name , elem_name ))
426- push(" mapping_summary <- c(mapping_summary," )
427- push(sprintf(" paste0('(', ds_name, ') ', %s, '[[\" ', %s, '\" ]]')" , dataset_name , elem_name ))
428- push(" )\n " )
429- push(" }\n " )
439+
440+ multiple <- (isTRUE(attr(elem , " zero_or_more" )) || isTRUE(attr(elem , " one_or_more" )))
441+ if (multiple ) {
442+ push(sprintf(" for (.elem in %s) {\n " , elem_name ))
443+ push(sprintf(" if(is.character(ds[[%s]][[.elem]])){\n " , dataset_name ))
444+ push(" mapping_summary <- c(mapping_summary," )
445+ push(sprintf(" paste0('(', ds_name, ') ', %s, '[[\" ', .elem, '\" ]]')" , dataset_name ))
446+ push(" )\n " )
447+ push(" }\n " )
448+ push(" }\n " )
449+ } else {
450+ push(sprintf(" if(is.character(ds[[%s]][[%s]])){\n " , dataset_name , elem_name ))
451+ push(" mapping_summary <- c(mapping_summary," )
452+ push(sprintf(" paste0('(', ds_name, ') ', %s, '[[\" ', %s, '\" ]]')" , dataset_name , elem_name ))
453+ push(" )\n " )
454+ push(" }\n " )
455+ }
456+
430457 }
431458 push(" }\n " )
432459
@@ -449,10 +476,20 @@ CM <- local({ # _C_hecked _M_odule
449476 elem <- spec $ elements [[elem_name ]]
450477 dataset_name <- elem [[" dataset_name" ]]
451478
452- push(sprintf(" if (is.character(res[[%s]][[%s]])) {\n " , dataset_name , elem_name ))
453- push(sprintf(" res[[%s]][[%s]] <- " , dataset_name , elem_name ))
454- push(sprintf(" as.factor(res[[%s]][[%s]])\n " , dataset_name , elem_name ))
455- push(" }\n " )
479+ multiple <- (isTRUE(attr(elem , " zero_or_more" )) || isTRUE(attr(elem , " one_or_more" )))
480+ if (multiple ) {
481+ push(sprintf(" for (.elem in %s) {\n " , elem_name ))
482+ push(sprintf(" if (is.character(res[[%s]][[.elem]])) {\n " , dataset_name ))
483+ push(sprintf(" res[[%s]][[.elem]] <- " , dataset_name ))
484+ push(sprintf(" as.factor(res[[%s]][[.elem]])\n " , dataset_name ))
485+ push(" }\n " )
486+ push(" }\n " )
487+ } else {
488+ push(sprintf(" if (is.character(res[[%s]][[%s]])) {\n " , dataset_name , elem_name ))
489+ push(sprintf(" res[[%s]][[%s]] <- " , dataset_name , elem_name ))
490+ push(sprintf(" as.factor(res[[%s]][[%s]])\n " , dataset_name , elem_name ))
491+ push(" }\n " )
492+ }
456493 }
457494
458495 push(" return(res)\n " )
0 commit comments