Efficient data-driven finite state machine
Nice work.


On findWeekdayDate() return, I'd expect a value that is enumerated like fWD_SUCCESS, fWD_FAIL, fWD_SUCCESS_for_foo_reason, fWD_FAIL_for_bar_reason, etc. Rather than magic numbers -1,0,3,....  It could end up being a simple bool.
As fsm[] is const struct fsmNode, I see no value in making a field const like const char target.  char target is simpler and sufficient.  OTOH, if there is some value, then next should also be const as in const struct fsmNode * const next.
Delay/remove #includes.

#include &lt;string.h&gt;  // Needed?
#include &lt;stdlib.h&gt;  // OK, for NULL
#include &lt;ctype.h&gt;   // Needed?

Style inconsistency.  Recommend empty for body to match other indentations.  

// for ( ; state-&gt;target &amp;&amp; *curr != state-&gt;target; ++state) 
//{ /* do nothing */ }
for ( ; state-&gt;target &amp;&amp; *curr != state-&gt;target; ++state) {
  /* do nothing */
}

Use an auto formatter.  The extra space betrays manual formatting as it is inconsistent with the rest of code.  Life is too short for manual formatting.

//             v
for (curr = str ; *curr; ++curr) {



Suggest adding link to software used to create FSM.