2323#include "match.h"
2424
2525typedef bool (* match_f ) (struct list_constraint * , const struct job * );
26+ typedef struct list_constraint * (* create_f ) (json_t * , flux_error_t * );
2627typedef int (* array_to_bitmask_f ) (json_t * , flux_error_t * );
2728
2829struct list_constraint {
@@ -84,6 +85,8 @@ static bool match_not (struct list_constraint *c, const struct job *job)
8485}
8586
8687static struct list_constraint * conditional_constraint (const char * type ,
88+ match_f match_not_cb ,
89+ create_f create_cb ,
8790 json_t * values ,
8891 flux_error_t * errp )
8992{
@@ -103,11 +106,11 @@ static struct list_constraint *conditional_constraint (const char *type,
103106 else if (streq (type , "or" ))
104107 c -> match = match_or ;
105108 else if (streq (type , "not" ))
106- c -> match = match_not ;
109+ c -> match = match_not_cb ;
107110 zlistx_set_destructor (c -> values , list_constraint_destructor );
108111
109112 json_array_foreach (values , index , entry ) {
110- struct list_constraint * cp = list_constraint_create (entry , errp );
113+ struct list_constraint * cp = create_cb (entry , errp );
111114 if (!cp )
112115 goto error ;
113116 if (!zlistx_add_end (c -> values , cp )) {
@@ -450,7 +453,11 @@ struct list_constraint *list_constraint_create (json_t *constraint,
450453 else if (streq (op , "since" ))
451454 return create_since_constraint (values , errp );
452455 else if (streq (op , "or" ) || streq (op , "and" ) || streq (op , "not" ))
453- return conditional_constraint (op , values , errp );
456+ return conditional_constraint (op ,
457+ match_not ,
458+ list_constraint_create ,
459+ values ,
460+ errp );
454461 else {
455462 errprintf (errp , "unknown constraint operator: %s" , op );
456463 return NULL ;
@@ -466,5 +473,75 @@ bool job_match (const struct job *job, struct list_constraint *constraint)
466473 return constraint -> match (constraint , job );
467474}
468475
476+ static bool match_not_checkempty (struct list_constraint * c , const struct job * job )
477+ {
478+ struct list_constraint * cp = zlistx_first (c -> values );
479+ bool ran_a_match = false;
480+ while (cp ) {
481+ if (!cp -> match (cp , job ))
482+ return true;
483+ if (cp -> match != match_empty )
484+ ran_a_match = true;
485+ cp = zlistx_next (c -> values );
486+ }
487+ /* if no real match callbacks were run, assume this conditional is true */
488+ if (!ran_a_match )
489+ return true;
490+ return false;
491+ }
492+
493+ struct list_constraint * state_constraint_create (json_t * constraint ,
494+ flux_error_t * errp )
495+ {
496+ const char * op ;
497+ json_t * values ;
498+
499+ if (!constraint || !json_is_object (constraint )) {
500+ errprintf (errp , "constraint must be JSON object" );
501+ return NULL ;
502+ }
503+ if (json_object_size (constraint ) > 1 ) {
504+ errprintf (errp , "constraint must only contain 1 element" );
505+ return NULL ;
506+ }
507+ json_object_foreach (constraint , op , values ) {
508+ if (!json_is_array (values )) {
509+ errprintf (errp , "operator %s values not an array" , op );
510+ return NULL ;
511+ }
512+ if (streq (op , "userid" )
513+ || streq (op , "name" )
514+ || streq (op , "queue" )
515+ || streq (op , "results" )
516+ || streq (op , "since" ))
517+ return list_constraint_new (errp );
518+ else if (streq (op , "states" ))
519+ return create_states_constraint (values , errp );
520+ else if (streq (op , "or" ) || streq (op , "and" ) || streq (op , "not" ))
521+ return conditional_constraint (op ,
522+ match_not_checkempty ,
523+ state_constraint_create ,
524+ values ,
525+ errp );
526+ else {
527+ errprintf (errp , "unknown constraint operator: %s" , op );
528+ return NULL ;
529+ }
530+ }
531+ return list_constraint_new (errp );
532+ }
533+
534+ bool state_match (flux_job_state_t state , struct list_constraint * constraint )
535+ {
536+ int valid_states = (FLUX_JOB_STATE_ACTIVE | FLUX_JOB_STATE_INACTIVE );
537+ struct job job ;
538+
539+ if (!state || (state & ~valid_states ) || !constraint )
540+ return false;
541+
542+ job .state = state ;
543+ return constraint -> match (constraint , & job );
544+ }
545+
469546/* vi: ts=4 sw=4 expandtab
470547 */
0 commit comments