Return values saved in history

On some contexts, we need to call one function to free some resource
allocated by another function based on the return value of the second
function. For example, every time pthread_mutex_trylock suceeds, you
need to unlock it, and only in those cases. While this could be done
with the return value sequence, it does not really work for a sequence
of custom fakes. Now we save the return values in the member
return_val_history, which works pretty much like arg_history, only
for the return values.
diff --git a/fakegen.rb b/fakegen.rb
index 3cfdbee..25a59d4 100644
--- a/fakegen.rb
+++ b/fakegen.rb
@@ -37,8 +37,10 @@
   define_reset_fake_macro
   define_declare_arg_helper
   define_declare_all_func_common_helper
+  define_declare_return_value_history
   define_save_arg_helper
   define_room_for_more_history
+  define_save_ret_history_helper
   define_save_arg_history_helper
   define_history_dropped_helper
   define_value_function_variables_helper
@@ -88,12 +90,25 @@
   putd "    unsigned int arg_histories_dropped; \\"
 end
 
+def define_declare_return_value_history
+  putd ""
+  putd "#define DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \\"
+  putd "    RETURN_TYPE return_val_history[FFF_ARG_HISTORY_LEN];"
+end
+
 def define_save_arg_helper
   putd ""
   putd "#define SAVE_ARG(FUNCNAME, n) \\"
   putd "    memcpy((void*)&FUNCNAME##_fake.arg##n##_val, (void*)&arg##n, sizeof(arg##n));"
 end
 
+def define_save_ret_history_helper
+  putd ""
+  putd "#define SAVE_RET_HISTORY(FUNCNAME, RETVAL) \\"
+  putd "    if ((FUNCNAME##_fake.call_count - 1) < FFF_ARG_HISTORY_LEN) \\"
+  putd "        memcpy((void *)&FUNCNAME##_fake.return_val_history[FUNCNAME##_fake.call_count - 1], (const void *) &RETVAL, sizeof(RETVAL)); \\"
+end
+
 def define_room_for_more_history
   putd ""
   putd "#define ROOM_FOR_MORE_HISTORY(FUNCNAME) \\"
@@ -139,10 +154,13 @@
   putd "#define RETURN_FAKE_RESULT(FUNCNAME) \\"
   putd "    if (FUNCNAME##_fake.return_val_seq_len){ /* then its a sequence */ \\"
   putd "        if(FUNCNAME##_fake.return_val_seq_idx < FUNCNAME##_fake.return_val_seq_len) { \\"
+  putd "            SAVE_RET_HISTORY(FUNCNAME, FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_idx]) \\"
   putd "            return FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_idx++]; \\"
   putd "        } \\"
+  putd "        SAVE_RET_HISTORY(FUNCNAME, FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_len-1]) \\"
   putd "        return FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_len-1]; /* return last element */ \\"
   putd "    } \\"
+  putd "    SAVE_RET_HISTORY(FUNCNAME, FUNCNAME##_fake.return_val) \\"
   putd "    return FUNCNAME##_fake.return_val; \\"
 end
 
@@ -261,6 +279,7 @@
     }
     putd "DECLARE_ALL_FUNC_COMMON \\"
     putd "DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \\" unless not is_value_function
+    putd "DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \\" unless not is_value_function
     putd "DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \\"
     output_custom_function_signature(arg_count, has_varargs, is_value_function)
     output_custom_function_array(arg_count, has_varargs, is_value_function)
@@ -330,15 +349,22 @@
       putd "  #{custom_fake_call}\\"
     end
     putd "    va_end(ap);\\"
+    putd "    SAVE_RET_HISTORY(FUNCNAME, ret); \\" unless not is_value_function
     putd "    return ret;\\" if is_value_function
     putd "}\\"
   else
     return_type = is_value_function ? "return " : ""
     putd "if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \\"
     putd "    if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \\"
-    putd "        #{return_type}FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](#{arg_list(arg_count)}); \\"
+    putd "        RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](#{arg_list(arg_count)}); \\" unless not is_value_function
+    putd "        SAVE_RET_HISTORY(FUNCNAME, ret); \\" unless not is_value_function
+    putd "        return ret; \\" unless not is_value_function
+    putd "        #{return_type}FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](#{arg_list(arg_count)}); \\" unless is_value_function
     putd "    } \\"
     putd "    else{ \\"
+    putd "        RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](#{arg_list(arg_count)}); \\" unless not is_value_function
+    putd "        SAVE_RET_HISTORY(FUNCNAME, ret); \\" unless not is_value_function
+    putd "        return ret; \\" unless not is_value_function
     putd "        #{return_type}FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](#{arg_list(arg_count)}); \\"
     putd "    } \\"
     putd "} \\"