Add implementation of some classes 07/200107/3
authorhyunho <hhstark.kang@samsung.com>
Tue, 19 Feb 2019 07:19:45 +0000 (16:19 +0900)
committerhyunho <hhstark.kang@samsung.com>
Wed, 20 Feb 2019 10:27:04 +0000 (19:27 +0900)
- ItemFactory
- ItemInflator
- AbstractItem
- GroupItem
- ButtonItem

Change-Id: I3e27193e8d9dd2e280fc1f894a1a4f12be03f3d3
Signed-off-by: hyunho <hhstark.kang@samsung.com>
27 files changed:
CMakeLists.txt
notification-ex/CMakeLists.txt
notification-ex/abstract_action.h
notification-ex/abstract_item.cc [new file with mode: 0644]
notification-ex/abstract_item.h
notification-ex/abstract_item_implementation.h [new file with mode: 0644]
notification-ex/action.h
notification-ex/bundle.cc [deleted file]
notification-ex/button_item.cc [new file with mode: 0644]
notification-ex/button_item.h [new file with mode: 0644]
notification-ex/ex_bundle.h
notification-ex/group_item.cc [new file with mode: 0644]
notification-ex/group_item.h [new file with mode: 0644]
notification-ex/group_item_implementation.h [new file with mode: 0644]
notification-ex/item.h
notification-ex/item_factory.cc [new file with mode: 0644]
notification-ex/item_factory.h [new file with mode: 0644]
notification-ex/item_inflator.cc [new file with mode: 0644]
notification-ex/item_inflator.h [new file with mode: 0644]
packaging/notification.spec
unittest/CMakeLists.txt
unittest/mock/app_common.h [new file with mode: 0644]
unittest/mock/fff.h [new file with mode: 0644]
unittest/mock/mock.cc [new file with mode: 0644]
unittest/mock/mock.h [new file with mode: 0644]
unittest/src/test_button_item.cc [new file with mode: 0644]
unittest/src/test_group_item.cc [new file with mode: 0644]

index e85ca6c..90ed25c 100644 (file)
@@ -1,5 +1,11 @@
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+
+ENABLE_TESTING()
+SET(NOTIFICATION_UNIT_TESTS notification-ex_unittests)
+ADD_TEST(NAME ${NOTIFICATION_UNIT_TESTS} COMMAND ${NOTIFICATION_UNIT_TESTS})
 
 ADD_SUBDIRECTORY(notification)
 ADD_SUBDIRECTORY(notification-ex)
 ADD_SUBDIRECTORY(unittest)
+
+ADD_DEPENDENCIES(notification-ex_unittests notification-ex)
index ccfaaa8..cebea32 100644 (file)
@@ -15,6 +15,7 @@ pkg_check_modules(notification-ex REQUIRED
        bundle
        dlog
        capi-appfw-app-control
+       capi-appfw-app-common
 )
 
 FOREACH(flag ${notification-ex_CFLAGS})
index 347c659..b9ea312 100644 (file)
@@ -32,12 +32,8 @@ namespace notification {
 namespace item {
 
 class AbstractItem;
-
 class EXPORT_API AbstractAction {
  public:
-  AbstractAction();
-  virtual ~AbstractAction();
-
   virtual bool IsLocal() const = 0;
   virtual void Execute(std::shared_ptr<AbstractItem> item) = 0;
   virtual Bundle Serialize() = 0;
diff --git a/notification-ex/abstract_item.cc b/notification-ex/abstract_item.cc
new file mode 100644 (file)
index 0000000..2503d88
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dlog.h>
+
+#include <memory>
+#include <algorithm>
+
+#include "notification-ex/exception.h"
+#include "notification-ex/abstract_item.h"
+#include "notification-ex/abstract_item_implementation.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "NOTIFICATION_EX"
+
+#define ABSTRACT_ITEM_TYPE_KEY "__ABSTRACT_ITEM_TYPE_KEY__"
+#define ABSTRACT_ITEM_ID_KEY "__ABSTRACT_ITEM_ID_KEY__"
+
+using namespace std;
+namespace notification {
+namespace item {
+
+AbstractItem::AbstractItem()
+  : impl_(new Impl(this)) {
+}
+
+AbstractItem::AbstractItem(AbstractItem::Type type,
+    std::shared_ptr<AbstractAction> action)
+  : impl_(new Impl(this, type, action)) {
+}
+
+AbstractItem::AbstractItem(std::string id, AbstractItem::Type type,
+    std::shared_ptr<AbstractAction> action)
+  : impl_(new Impl(this, id, type, action)) {
+}
+
+AbstractItem::Impl::Impl(AbstractItem* parent, string id,
+    AbstractItem::Type type, std::shared_ptr<AbstractAction> action)
+  : id_(id), type_(type), action_(action), parent_(parent) {
+  LOGI("GroupItem created");
+}
+
+AbstractItem::Impl::Impl(AbstractItem* parent,
+    AbstractItem::Type type, std::shared_ptr<AbstractAction> action)
+  : type_(type), action_(action), parent_(parent) {
+  LOGI("GroupItem created");
+}
+
+AbstractItem::Impl::Impl(AbstractItem* parent)
+  : parent_(parent) {
+  LOGI("GroupItem created");
+}
+
+AbstractItem::~AbstractItem() = default;
+
+Bundle AbstractItem::Serialize() {
+  Bundle b;
+  b.Add(ABSTRACT_ITEM_TYPE_KEY, to_string((int)impl_->type_));
+  b.Add(ABSTRACT_ITEM_ID_KEY, impl_->id_);
+  return b;
+}
+
+void AbstractItem::Deserialize(Bundle b) {
+  string type_str = b.GetString(ABSTRACT_ITEM_TYPE_KEY);
+  if (type_str.empty())
+    THROW(NOTIFICATION_ERROR_IO_ERROR);
+
+  string id_str = b.GetString(ABSTRACT_ITEM_ID_KEY);
+  impl_->id_ = id_str;
+  impl_->type_ = static_cast<AbstractItem::Type>(strtol(type_str.c_str(), NULL, 10));
+}
+
+string AbstractItem::GetId() const {
+ return impl_->id_;
+}
+
+shared_ptr<AbstractAction> AbstractItem::GetAction() const {
+  return impl_->action_;
+}
+
+shared_ptr<Style> AbstractItem::GetStyle() const {
+  return impl_->style_;
+}
+
+void AbstractItem::SetStyle(shared_ptr<Style> style) {
+  impl_->style_ = style;
+}
+
+void AbstractItem::SetLEDInfo(std::shared_ptr<LEDInfo> led) {
+  impl_->led_ = led;
+}
+
+std::shared_ptr<LEDInfo> AbstractItem::GetLEDInfo() const {
+  return impl_->led_;
+}
+
+AbstractItem::Type AbstractItem::GetType() const {
+  return impl_->type_;
+}
+
+AbstractItem::Type AbstractItem::GetType(Bundle b) {
+  string type_str = b.GetString(ABSTRACT_ITEM_TYPE_KEY);
+  if (type_str.empty())
+    THROW(NOTIFICATION_ERROR_IO_ERROR);
+  return static_cast<AbstractItem::Type>(strtol(type_str.c_str(), NULL, 10));
+}
+
+void AbstractItem::SetVisible(bool visible) {
+  impl_->visible_ = visible;
+}
+
+void AbstractItem::SetEnable(bool enable) {
+  impl_->enable_ = enable;
+}
+
+void AbstractItem::AddReceiver(std::string receiver_group) {
+  impl_->receiver_group_list_.push_back(receiver_group);
+}
+
+void AbstractItem::RemoveReceiver(std::string receiver_group) {
+  impl_->receiver_group_list_.remove(receiver_group);
+}
+
+bool AbstractItem::CanReceive(std::string id) const {
+  list<string>::iterator iter =
+    std::find(impl_->receiver_group_list_.begin(),
+      impl_->receiver_group_list_.end(), id);
+  return !(iter == impl_->receiver_group_list_.end());
+}
+
+void AbstractItem::SetPolicy(AbstractItem::Policy policy) {
+  impl_->policy_ = policy;
+}
+
+AbstractItem::Policy AbstractItem::GetPolicy() const {
+  return impl_->policy_;
+}
+
+int AbstractItem::GetVersion() const {
+  return impl_->version_;
+}
+
+void AbstractItem::SetVersion(int ver) {
+  impl_->version_ = ver;
+}
+
+int AbstractItem::GetHideTime() const {
+  return impl_->hide_time_;
+}
+
+int AbstractItem::GetDeleteTime() const {
+  return impl_->delete_time_;
+}
+
+string AbstractItem::GetChannel() const {
+  return impl_->channel_;
+}
+
+void AbstractItem::SetChannel(string channel) {
+  impl_->channel_ = channel;
+}
+
+}  // namespace item
+}  // namespace notification
index 2919163..e63dd04 100644 (file)
@@ -43,7 +43,7 @@ class EXPORT_API Color {
   Color(unsigned char a, unsigned char r, unsigned char g, unsigned char b)
     : a_(a), r_(r), g_(g), b_(b) {
   }
-  virtual ~Color();
+  virtual ~Color() = default;
 
   unsigned char GetAVal() const {
     return a_;
@@ -76,7 +76,7 @@ class EXPORT_API Padding {
   Padding(int left, int top, int right, int bottom)
     : left_(left), top_(top), right_(right), bottom_(bottom) {
   }
-  virtual ~Padding();
+  virtual ~Padding() = default;
 
   int GeLeft() const {
     return left_;
@@ -108,7 +108,7 @@ class EXPORT_API Geometry {
   }
   Geometry(int x, int y, int w, int h) : x_(x), y_(y), w_(w), h_(h) {
   }
-  virtual ~Geometry();
+  virtual ~Geometry() = default;
 
   int GetX() const {
     return x_;
@@ -132,8 +132,10 @@ class EXPORT_API Geometry {
 
 class EXPORT_API Style {
  public:
+  Style() {
+  }
   Style(Color color, Padding padding, Geometry geometry);
-  virtual ~Style();
+  virtual ~Style() = default;
 
   Padding GetPadding() const;
   Color GetColor() const;
@@ -151,7 +153,7 @@ class EXPORT_API LEDInfo {
     Color(0, 0, 0, 0);
   }
   explicit LEDInfo(Color color);
-  virtual ~LEDInfo();
+  virtual ~LEDInfo() = default;
 
   void SetOffPeriod(int ms);
   void SetOnPeriod(int ms);
@@ -180,13 +182,18 @@ class EXPORT_API AbstractItem {
   };
 
   enum Policy {
+    None,
     OnBootClear,
     SimMode,
   };
 
  public:
   AbstractItem();
-  virtual ~AbstractItem();
+  AbstractItem(Type type,
+      std::shared_ptr<AbstractAction> action = std::shared_ptr<AbstractAction>({}));
+  AbstractItem(std::string id, Type type,
+      std::shared_ptr<AbstractAction> action = std::shared_ptr<AbstractAction>({}));
+  virtual ~AbstractItem() = 0;
 
   virtual Bundle Serialize() = 0;
   virtual void Deserialize(Bundle b) = 0;
@@ -194,21 +201,30 @@ class EXPORT_API AbstractItem {
   std::string GetId() const;
   void SetId(std::string id);
   std::shared_ptr<AbstractAction> GetAction() const;
-  Style GetStyle() const;
+  void SetAction(std::shared_ptr<AbstractAction> action) const;
+  std::shared_ptr<Style> GetStyle() const;
+  void SetStyle(std::shared_ptr<Style> style);
   Type GetType() const;
+  static AbstractItem::Type GetType(Bundle b);
   void SetVisible(bool visible);
   void SetEnable(bool enable);
   void AddReceiver(std::string receiver_group);
   void RemoveReceiver(std::string receiver_group);
   bool CanReceive(std::string id) const;
   void SetPolicy(Policy policy);
+  Policy GetPolicy() const;
   int GetVersion() const;
   void SetVersion(int ver);
   int GetHideTime() const;
   int GetDeleteTime() const;
+  std::string GetChannel() const;
+  void SetChannel(std::string channel);
+  void SetLEDInfo(std::shared_ptr<LEDInfo> led);
+  std::shared_ptr<LEDInfo> GetLEDInfo() const;
 
  private:
-  Style style_;
+  class Impl;
+  std::unique_ptr<Impl> impl_;
 };  // class AbstractItem
 
 }  // namespace item
diff --git a/notification-ex/abstract_item_implementation.h b/notification-ex/abstract_item_implementation.h
new file mode 100644 (file)
index 0000000..64f25eb
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NOTIFICATION_EX_ABSTRACT_ITEM_IMPLEMENTATION_H_
+#define NOTIFICATION_EX_ABSTRACT_ITEM_IMPLEMENTATION_H_
+
+#include <string>
+#include <memory>
+#include <list>
+
+#include "notification-ex/abstract_item.h"
+
+namespace notification {
+namespace item {
+
+class AbstractItem::Impl {
+ public:
+  virtual ~Impl() = default;
+
+ private:
+  Impl(AbstractItem* parent);
+  Impl(AbstractItem* parent, AbstractItem::Type type,
+      std::shared_ptr<AbstractAction> action = std::shared_ptr<AbstractAction>({}));
+  Impl(AbstractItem* parent, std::string id, AbstractItem::Type type,
+      std::shared_ptr<AbstractAction> action = std::shared_ptr<AbstractAction>({}));
+
+ private:
+  friend class AbstractItem;
+
+  std::string channel_;
+  std::string id_;
+  std::shared_ptr<LEDInfo> led_ = nullptr;
+  Policy policy_ = None;
+  std::shared_ptr<Style> style_ = nullptr;
+  AbstractItem::Type type_;
+  bool visible_ = true;
+  bool enable_ = true;
+  int version_ = 1;
+  int hide_time_ = 0;
+  int delete_time_ = 0;
+  std::list<std::string> receiver_group_list_;
+  std::string can_receive_;
+  std::shared_ptr<AbstractAction> action_;
+  AbstractItem* parent_;
+};
+
+}  // namespace item
+}  // namespace notification
+
+#endif  // NOTIFICATION_EX_ABSTRACT_ITEM_IMPLEMENTATION_H_
index f6abb2e..5b9c387 100644 (file)
@@ -33,12 +33,27 @@ class EXPORT_API AppControlAction  : public AbstractAction {
   explicit AppControlAction(app_control_h control);
   virtual ~AppControlAction();
 
-  bool IsLocal() const override;
-  void Execute(std::shared_ptr<AbstractItem> item) override;
-  Bundle Serialize() override;
-  void Deserialize(Bundle b) override;
-  void SetAppControl(app_control_h control);
-  app_control_h GetAppControl() const;
+  bool IsLocal() const override {
+    return true;
+  }
+
+  void Execute(std::shared_ptr<AbstractItem> item) override {
+  }
+
+  Bundle Serialize() override {
+    Bundle b;
+    return b;
+  }
+
+  void Deserialize(Bundle b) override {
+  }
+
+  void SetAppControl(app_control_h control) {
+  }
+
+  app_control_h GetAppControl() const {
+    return control_;
+  }
 
  private:
   app_control_h control_ = nullptr;
@@ -49,10 +64,20 @@ class EXPORT_API ReplyAction  : public AbstractAction {
   ReplyAction();
   virtual ~ReplyAction();
 
-  bool IsLocal() const override;
-  void Execute(std::shared_ptr<AbstractItem> item) override;
-  Bundle Serialize() override;
-  void Deserialize(Bundle b) override;
+  bool IsLocal() const override {
+    return true;
+  }
+
+  void Execute(std::shared_ptr<AbstractItem> item) override {
+  }
+
+  Bundle Serialize() override {
+    Bundle b;
+    return b;
+  }
+
+  void Deserialize(Bundle b) override {
+  }
 };
 
 class EXPORT_API VisibilityAction  : public AbstractAction {
@@ -60,14 +85,28 @@ class EXPORT_API VisibilityAction  : public AbstractAction {
   VisibilityAction();
   virtual ~VisibilityAction();
 
-  bool IsLocal() const override;
-  void Execute(std::shared_ptr<AbstractItem> item) override;
-  Bundle Serialize() override;
-  void Deserialize(Bundle b) override;
-  void SetVisibility(std::string id, bool visible);
+  bool IsLocal() const override {
+    return true;
+  }
+
+  void Execute(std::shared_ptr<AbstractItem> item) override {
+  }
+
+  Bundle Serialize() override {
+    Bundle b;
+    return b;
+  }
+
+  void Deserialize(Bundle b) override {
+  }
+
+  void SetVisibility(std::string id, bool visible) {
+    id_ = id;
+    visible_ = visible;
+  }
 
  private:
-  std::string id_ = NULL;
+  std::string id_;
   bool visible_ = false;
 };
 
diff --git a/notification-ex/bundle.cc b/notification-ex/bundle.cc
deleted file mode 100644 (file)
index a0b9b35..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (c) 2019 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "notification-ex/ex_bundle.h"
-#include "notification-ex/exception.h"
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-
-#define LOG_TAG "NOTIFICATION_EX"
-
-namespace notification {
-namespace item {
-
-Bundle::Bundle() {
-  raw_ = bundle_create();
-  if (raw_ == NULL)
-    THROW(NOTIFICATION_ERROR_OUT_OF_MEMORY);
-}
-
-Bundle::Bundle(std::string raw) {
-  if (!raw.empty()) {
-    raw_ = bundle_decode(reinterpret_cast<const bundle_raw*>(raw.c_str()),
-                         raw.length());
-    if (raw_ == NULL) {
-      int ret = get_last_result();
-      if (ret == BUNDLE_ERROR_OUT_OF_MEMORY)
-        THROW(NOTIFICATION_ERROR_OUT_OF_MEMORY);
-      else
-        THROW(NOTIFICATION_ERROR_INVALID_PARAMETER);
-    }
-  } else {
-    raw_ = bundle_create();
-    if (raw_ == NULL)
-      THROW(NOTIFICATION_ERROR_OUT_OF_MEMORY);
-  }
-}
-
-Bundle::Bundle(bundle* raw) {
-  raw_ = bundle_dup(raw);
-  if (raw_ == NULL)
-    THROW(NOTIFICATION_ERROR_OUT_OF_MEMORY);
-}
-
-Bundle::Bundle(Bundle&& b) : raw_(b.raw_) {
-  b.raw_ = nullptr;
-}
-
-Bundle& Bundle::operator = (Bundle&& b) {
-  raw_ = b.raw_;
-  b.raw_ = nullptr;
-  return *this;
-}
-
-Bundle::Bundle(const Bundle& b) : raw_(bundle_dup(b.raw_)) {
-}
-
-Bundle& Bundle::operator = (const Bundle& b) {
-  raw_ = bundle_dup(b.raw_);
-  if (raw_ == NULL)
-    THROW(NOTIFICATION_ERROR_OUT_OF_MEMORY);
-  return *this;
-}
-
-const bundle* Bundle::GetConstRaw() const {
-  return raw_;
-}
-
-bundle* Bundle::GetRaw() {
-  return raw_;
-}
-
-const char* Bundle::ToString() {
-  int str_len = 0;
-  bundle_raw* temp;
-
-  if (str_raw_ != NULL)
-    return str_raw_;
-
-  bundle_encode(raw_, &temp, &str_len);
-
-  str_raw_ = reinterpret_cast<char*>(temp);
-  return str_raw_;
-}
-
-Bundle::~Bundle() {
-  if (raw_) {
-    bundle_free(raw_);
-    raw_ = NULL;
-  }
-  if (str_raw_) {
-    free(str_raw_);
-    str_raw_ = NULL;
-  }
-}
-
-} //namespace item
-} //namespace notification
diff --git a/notification-ex/button_item.cc b/notification-ex/button_item.cc
new file mode 100644 (file)
index 0000000..98c2c78
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dlog.h>
+
+#include <memory>
+
+#include "notification-ex/button_item.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "NOTIFICATION_EX"
+#define BUTTON_TITLE_KEY "__BUTTON_TITLE_KEY__"
+
+namespace notification {
+namespace item {
+
+ButtonItem::ButtonItem(string title,
+      std::shared_ptr<AbstractAction> action)
+  : AbstractItem(AbstractItem::Button, action), title_(title) {
+}
+
+ButtonItem::ButtonItem(string id, string title,
+      std::shared_ptr<AbstractAction> action)
+  : AbstractItem(id, AbstractItem::Button, action), title_(title) {
+}
+ButtonItem::~ButtonItem() = default;
+
+Bundle ButtonItem::Serialize() {
+  Bundle b;
+  b = AbstractItem::Serialize();
+  b.Add(BUTTON_TITLE_KEY, title_);
+  return b;
+}
+
+void ButtonItem::Deserialize(Bundle b) {
+  AbstractItem::Deserialize(b);
+  title_ = b.GetString(BUTTON_TITLE_KEY);
+}
+
+shared_ptr<AbstractItem> ButtonItem::FindByID(std::string id) {
+  if (GetId() == id)
+    return shared_ptr<AbstractItem>(this);
+  return nullptr;
+}
+
+std::string ButtonItem::GetTitle() const {
+  return title_;
+}
+
+}  // namespace item
+}  // namespace notification
diff --git a/notification-ex/button_item.h b/notification-ex/button_item.h
new file mode 100644 (file)
index 0000000..ae5765f
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NOTIFICATION_EX_BUTTON_ITEM_H_
+#define NOTIFICATION_EX_BUTTON_ITEM_H_
+
+#include <string>
+#include <memory>
+#include <list>
+
+#include "notification-ex/abstract_item.h"
+
+using namespace std;
+namespace notification {
+namespace item {
+
+class EXPORT_API ButtonItem : public AbstractItem {
+ public:
+  ButtonItem(std::string id, std::string title,
+      std::shared_ptr<AbstractAction> action = std::shared_ptr<AbstractAction>({}));
+  ButtonItem(std::string title,
+      std::shared_ptr<AbstractAction> action = std::shared_ptr<AbstractAction>({}));
+  virtual ~ButtonItem();
+
+  Bundle Serialize() override;
+  void Deserialize(Bundle b) override;
+  std::shared_ptr<AbstractItem> FindByID(std::string id) override;
+  std::string GetTitle() const;
+
+ private:
+  std::string title_;
+};  // class ButtonItem
+
+}  // namespace item
+}  // namespace notification
+
+#endif  // NOTIFICATION_EX_BUTTON_ITEM_H_
index 894f8b3..1640f00 100644 (file)
 #include <bundle.h>
 
 #include <string>
+#include <vector>
+#include <memory>
+#include <cstdio>
+
+#include <dlog.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "NOTIFICATION_EX"
 
 #ifndef EXPORT_API
 #define EXPORT_API __attribute__((visibility("default")))
 
 namespace notification {
 namespace item {
-
-class EXPORT_API Bundle {
+class EXPORT_API Bundle final {
  public:
-  Bundle();
-  explicit Bundle(std::string raw);
-  explicit Bundle(bundle* raw);
-  ~Bundle();
+  using BundleRaw =
+      std::pair<std::unique_ptr<bundle_raw, decltype(std::free)*>, int>;
+
+  class KeyInfo final {
+   public:
+    KeyInfo(const bundle_keyval_t* handle, std::string name)
+       : handle_(handle), name_(std::move(name)) {}
+
+    bundle_type GetType() const {
+      return static_cast<bundle_type>(
+          bundle_keyval_get_type(const_cast<bundle_keyval_t*>(handle_)));
+    }
+
+    bool IsArray() const {
+      return bundle_keyval_type_is_array(const_cast<bundle_keyval_t*>(handle_));
+    }
+
+    const std::string& GetName() const {
+      return name_;
+    }
+
+   private:
+    const bundle_keyval_t* handle_;
+    std::string name_;
+  };
+
+  Bundle() {
+    handle_ = bundle_create();
+  }
+
+  Bundle(BundleRaw raw) {
+    handle_ = bundle_decode(raw.first.get(), raw.second);
+  }
+
+
+  Bundle(const std::string& raw) {
+    handle_ = bundle_decode(reinterpret_cast<const bundle_raw*>(raw.c_str()),
+                         raw.length());
+  }
+
+  Bundle(bundle* b, bool copy = true, bool own = true)
+      : own_(own), copy_(copy) {
+    if (!copy_)
+      handle_ = b;
+    else
+      handle_ = bundle_dup(b);
+  }
+
+  ~Bundle() {
+    if (handle_ && (own_ || copy_))
+      bundle_free(handle_);
+  }
+
+  Bundle(const Bundle& b) {
+    handle_ = bundle_dup(b.handle_);
+  }
+
+  Bundle& operator = (const Bundle& b) {
+    handle_ = bundle_dup(b.handle_);
+    return *this;
+  }
+
+  Bundle(Bundle&& b) noexcept {
+    handle_ = b.handle_;
+    b.handle_ = nullptr;
+  }
+
+  Bundle& operator = (Bundle&& b) noexcept {
+    handle_ = b.handle_;
+    b.handle_ = nullptr;
+    return *this;
+  }
+
+  std::vector<KeyInfo> GetKeys() {
+    std::vector<KeyInfo> v;
+
+    bundle_foreach(handle_, [](const char *key, const int type,
+        const bundle_keyval_t *kv, void *user_data) {
+        auto* v = static_cast<std::vector<KeyInfo>*>(user_data);
+        v->emplace_back(kv, key);
+      }, &v);
+
+    return v;
+  }
+
+  int Add(const std::string& key, const std::string& val) {
+     return bundle_add_str(handle_, key.c_str(), val.c_str());
+  }
+
+  int Add(const std::string& key, const std::vector<std::string>& val) {
+    std::vector<const char*> v;
+    for (auto& i : val) {
+      v.push_back(i.c_str());
+    }
+
+    return bundle_add_str_array(handle_, key.c_str(), v.data(), v.size());
+  }
+
+  int Add(const std::string& key, const std::vector<unsigned char>& val) {
+    return bundle_add_byte(handle_, key.c_str(), val.data(), val.size());
+  }
+
+  int Remove(const std::string& key) {
+    return bundle_del(handle_, key.c_str());
+  }
+
+  std::string GetString(const std::string& key) const {
+    char* str = nullptr;
+    bundle_get_str(handle_, key.c_str(), &str);
+
+    if (!str)
+      return "";
+
+    return std::string(str);
+  }
+
+  std::vector<std::string> GetStringArray(const std::string& key) const {
+    std::vector<std::string> v;
+
+    const char** str_array = nullptr;
+    int len = 0;
+
+    str_array = bundle_get_str_array(handle_, key.c_str(), &len);
+
+    for (int i = 0; i < len; i++) {
+      v.emplace_back(str_array[i]);
+    }
+
+    return v;
+  }
+
+  std::vector<unsigned char> GetByte(const std::string& key) const {
+    size_t size;
+    unsigned char* bytes = nullptr;
+    bundle_get_byte(handle_, key.c_str(),
+        reinterpret_cast<void**>(&bytes), &size);
+    return std::vector<unsigned char>(bytes, bytes + size);
+  }
+
+  BundleRaw ToRaw() {
+    bundle_raw* raw = nullptr;
+    int len = 0;
+    bundle_encode(handle_, &raw, &len);
+
+    return BundleRaw(
+        std::unique_ptr<bundle_raw, decltype(std::free)*>(raw, std::free), len);
+  }
+
+  int GetCount() const {
+    return bundle_get_count(handle_);
+  }
 
-  Bundle(const Bundle&);
-  Bundle& operator=(const Bundle&);
+  bundle_type GetType(const std::string& key) const {
+    return static_cast<bundle_type>(bundle_get_type(handle_, key.c_str()));
+  }
 
-  Bundle(Bundle && other);
-  Bundle& operator=(Bundle && other);
+  bundle* GetHandle() const {
+    return handle_;
+  }
 
-  const bundle* GetConstRaw() const;
-  bundle* GetRaw();
-  const char* ToString();
+  bundle* Detach() {
+    auto* h = handle_;
+    handle_ = nullptr;
+    return h;
+  }
 
  private:
-  bundle* raw_ = NULL;
-  char* str_raw_ = NULL;
+  bundle* handle_;
+  bool own_ = true;
+  bool copy_ = true;
 };
 
 }  // namespace item
diff --git a/notification-ex/group_item.cc b/notification-ex/group_item.cc
new file mode 100644 (file)
index 0000000..451a018
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dlog.h>
+#include <app_common.h>
+
+#include <memory>
+#include <vector>
+
+#include "notification-ex/group_item.h"
+#include "notification-ex/group_item_implementation.h"
+#include "notification-ex/item_factory.h"
+#include "notification-ex/exception.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "NOTIFICATION_EX"
+#define GROUP_CHILDREN_KEY "__GROUP_CHILDREN_KEY__"
+#define GROUP_CHILDREN_TYPE_KEY "__GROUP_CHILDREN_TYPE_KEY__"
+#define GROUP_DIRECTION_KEY "__GROUP_DIRECTION_KEY__"
+#define GROUP_DIRECTION_VERTICAL "VERTICAL"
+#define GROUP_DIRECTION_HORIZONTAL "HORIZONTAL"
+#define GROUP_APP_LABEL_KEY "__GROUP_APP_LABEL_KEY__"
+
+using namespace std;
+namespace notification {
+namespace item {
+
+GroupItem::GroupItem(string id, shared_ptr<AbstractAction> action)
+  : AbstractItem(id, AbstractItem::Group), impl_(new Impl(this)) {
+}
+
+GroupItem::GroupItem(shared_ptr<AbstractAction> action)
+  : AbstractItem(AbstractItem::Group), impl_(new Impl(this)) {
+}
+
+GroupItem::Impl::Impl(GroupItem* parent)
+  : parent_(parent) {
+  LOGI("GroupItem created");
+}
+
+GroupItem::~GroupItem() {
+}
+
+Bundle GroupItem::Serialize() {
+  Bundle b;
+  b = AbstractItem::Serialize();
+  b.Add(GROUP_DIRECTION_KEY, impl_->is_vertical_ ?
+      GROUP_DIRECTION_VERTICAL : GROUP_DIRECTION_HORIZONTAL);
+  if (!impl_->app_label_.empty())
+    b.Add(GROUP_APP_LABEL_KEY, impl_->app_label_);
+
+  if (impl_->children_list_.size() == 0)
+    return b;
+
+  vector<std::string> arr;
+  for (auto& i : impl_->children_list_) {
+    Bundle serialized = i.get()->Serialize();
+    serialized.Add(
+        GROUP_CHILDREN_TYPE_KEY, to_string((int)i.get()->GetType()));
+    char* str = strdup(reinterpret_cast<char*>(serialized.ToRaw().first.get()));
+    arr.push_back(str);
+  }
+  b.Add(GROUP_CHILDREN_KEY, arr);
+
+  return b;
+}
+
+void GroupItem::Deserialize(Bundle b) {
+  AbstractItem::Deserialize(b);
+  impl_->is_vertical_ =
+      (b.GetString(GROUP_DIRECTION_KEY) == GROUP_DIRECTION_VERTICAL);
+  impl_->app_label_ = b.GetString(GROUP_APP_LABEL_KEY);
+
+  vector<string> str_arr = b.GetStringArray(GROUP_CHILDREN_KEY);
+  if (str_arr.size() == 0)
+    return;
+
+  ItemFactory factory;
+  for (string str : str_arr) {
+    Bundle serialized(str);
+    string type_str = serialized.GetString(GROUP_CHILDREN_TYPE_KEY);
+    AbstractItem::Type child_type =
+        static_cast<AbstractItem::Type>(strtol(type_str.c_str(), NULL, 10));
+    shared_ptr<AbstractItem> child = factory.CreateItem(child_type);
+    child.get()->Deserialize(serialized);
+    AddChild(child);
+  }
+}
+
+shared_ptr<AbstractItem> GroupItem::FindByID(std::string id) {
+  for (auto& i : impl_->children_list_) {
+    if (i.get()->GetId() == id)
+      return i;
+  }
+  return nullptr;
+}
+
+void GroupItem::AddChild(shared_ptr<AbstractItem> child) {
+  impl_->children_list_.emplace_back(child);
+}
+
+void GroupItem::RemoveChild(string itemId) {
+  for (auto& i : impl_->children_list_) {
+    if (i.get()->GetId() == itemId) {
+      impl_->children_list_.remove(i);
+      break;
+    }
+  }
+}
+
+list<shared_ptr<AbstractItem>> GroupItem::GetChildren() {
+  return impl_->children_list_;
+}
+
+void GroupItem::SetDirection(bool vertical) {
+  impl_->is_vertical_ = vertical;
+}
+
+bool GroupItem::IsVertical() {
+  return impl_->is_vertical_;
+}
+
+string GroupItem::GetAppLabel() {
+ if (impl_->app_label_.empty()) {
+   char* name;
+   int ret = app_get_name(&name);
+   if (ret != APP_ERROR_NONE)
+     THROW(NOTIFICATION_ERROR_IO_ERROR);
+   impl_->app_label_ = string(name);
+ }
+ return impl_->app_label_;
+}
+
+}  // namespace item
+}  // namespace notification
diff --git a/notification-ex/group_item.h b/notification-ex/group_item.h
new file mode 100644 (file)
index 0000000..319ab57
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NOTIFICATION_EX_GROUP_ITEM_H_
+#define NOTIFICATION_EX_GROUP_ITEM_H_
+
+#include <string>
+#include <memory>
+#include <list>
+
+#include "notification-ex/abstract_item.h"
+
+namespace notification {
+namespace item {
+
+class EXPORT_API GroupItem : public AbstractItem {
+ public:
+  GroupItem(std::shared_ptr<AbstractAction> action = std::shared_ptr<AbstractAction>({}));
+  GroupItem(std::string id,
+      std::shared_ptr<AbstractAction> action = std::shared_ptr<AbstractAction>({}));
+  virtual ~GroupItem();
+
+ public:
+  virtual Bundle Serialize() override;
+  virtual void Deserialize(Bundle b) override;
+  virtual std::shared_ptr<AbstractItem> FindByID(std::string id) override;
+
+  void SetDirection(bool vertical);
+  bool IsVertical();
+  std::string GetAppLabel();
+  void AddChild(std::shared_ptr<AbstractItem> child);
+  void RemoveChild(std::string itemId);
+  std::list<std::shared_ptr<AbstractItem>> GetChildren();
+
+ private:
+  class Impl;
+  std::unique_ptr<Impl> impl_;
+};
+
+}  // namespace item
+}  // namespace notification
+
+#endif  // NOTIFICATION_EX_GROUP_ITEM_H_
diff --git a/notification-ex/group_item_implementation.h b/notification-ex/group_item_implementation.h
new file mode 100644 (file)
index 0000000..df83034
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NOTIFICATION_EX_GROUP_ITEM_IMPLEMENTATION_H_
+#define NOTIFICATION_EX_GROUP_ITEM_IMPLEMENTATION_H_
+
+#include <string>
+#include <memory>
+#include <list>
+
+#include "notification-ex/group_item.h"
+
+namespace notification {
+namespace item {
+
+class GroupItem::Impl {
+ public:
+  virtual ~Impl() = default;
+
+ private:
+  Impl(GroupItem* parent);
+
+ private:
+  friend class GroupItem;
+
+  std::list<std::shared_ptr<AbstractItem>> children_list_;
+  bool is_vertical_ = true;
+  std::string app_label_;
+  GroupItem* parent_;
+
+};
+
+}  // namespace item
+}  // namespace notification
+
+#endif  // NOTIFICATION_EX_GROUP_ITEM_IMPLEMENTATION_H_
index adab148..46c4177 100644 (file)
 namespace notification {
 namespace item {
 
-class EXPORT_API GroupItem : public AbstractItem {
- public:
-  GroupItem();
-  virtual ~GroupItem();
-
-  Bundle Serialize() override;
-  void Deserialize(Bundle b) override;
-  std::shared_ptr<AbstractItem> FindByID(std::string id) override;
-  void AddChild(std::shared_ptr<AbstractItem> child);
-  void Remove(std::string itemId);
-  std::list<std::shared_ptr<AbstractItem>> GetChildren() const;
-  int GetChannel() const;
-  void SetChannel(int channel);
-  void SetDirection(bool vertical);
-  bool IsVertical() const;
-  std::string GetAppLabel() const;
-
-
- private:
-  bool Vertical_ = true;
-  std::string channel_ = nullptr;
-  std::string id_ = nullptr;
-  LEDInfo led_;
-  std::string itemId_ = nullptr;
-};  // class GroupItem
-
 class EXPORT_API TextItem : public AbstractItem {
  public:
   TextItem(std::string text);
@@ -118,20 +92,6 @@ class EXPORT_API ImageItem : public AbstractItem {
   std::string imagePath_ = nullptr;
 };  // class ImageItem
 
-class EXPORT_API ButtonItem : public AbstractItem {
- public:
-  ButtonItem(std::string title);
-  virtual ~ButtonItem();
-
-  Bundle Serialize() override;
-  void Deserialize(Bundle b) override;
-  std::shared_ptr<AbstractItem> FindByID(std::string id) override;
-  std::string GetTitle() const;
-
- private:
-  std::string title_ = nullptr;
-};  // class ButtonItem
-
 class EXPORT_API ProgressItem : public AbstractItem {
  public:
   ProgressItem(float min, float max, float current);
diff --git a/notification-ex/item_factory.cc b/notification-ex/item_factory.cc
new file mode 100644 (file)
index 0000000..464bce7
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dlog.h>
+
+#include <memory>
+
+#include "notification-ex/item_factory.h"
+#include "notification-ex/button_item.h"
+#include "notification-ex/group_item.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "NOTIFICATION_EX"
+
+using namespace std;
+namespace notification {
+namespace item {
+
+shared_ptr<AbstractItem> ItemFactory::CreateItem(AbstractItem::Type type) {
+  switch (type) {
+  case AbstractItem::Text :
+    return make_shared<ButtonItem>("");
+  case AbstractItem::Icon :
+    return make_shared<ButtonItem>("");
+  case AbstractItem::Image :
+    return make_shared<ButtonItem>("");
+  case AbstractItem::Button :
+    return make_shared<ButtonItem>("");
+  case AbstractItem::ChatMessage :
+    return make_shared<ButtonItem>("");
+  case AbstractItem::CheckBox :
+    return make_shared<ButtonItem>("");
+  case AbstractItem::IconText :
+    return make_shared<ButtonItem>("");
+  case AbstractItem::InputSelector :
+    return make_shared<ButtonItem>("");
+  case AbstractItem::Group :
+    return make_shared<GroupItem>();
+  case AbstractItem::Effect :
+    return make_shared<ButtonItem>("");
+  case AbstractItem::Progress :
+    return make_shared<ButtonItem>("");
+  case AbstractItem::Custom :
+    return make_shared<ButtonItem>("");
+  }
+
+  return nullptr;
+}
+
+}  // namespace item
+}  // namespace notification
diff --git a/notification-ex/item_factory.h b/notification-ex/item_factory.h
new file mode 100644 (file)
index 0000000..e28d912
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NOTIFICATION_EX_ITEM_FACTORY_H_
+#define NOTIFICATION_EX_ITEM_FACTORY_H_
+
+#include <string>
+#include <memory>
+#include <list>
+
+#include "notification-ex/abstract_item.h"
+
+namespace notification {
+namespace item {
+
+class EXPORT_API ItemFactory {
+ public:
+  std::shared_ptr<AbstractItem> CreateItem(AbstractItem::Type type);
+};
+
+}  // namespace item
+}  // namespace notification
+
+#endif  // NOTIFICATION_EX_ITEM_FACTORY_H_
diff --git a/notification-ex/item_inflator.cc b/notification-ex/item_inflator.cc
new file mode 100644 (file)
index 0000000..183f940
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dlog.h>
+
+#include <memory>
+
+#include "notification-ex/item_factory.h"
+#include "notification-ex/item_inflator.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "NOTIFICATION_EX"
+
+using namespace std;
+namespace notification {
+namespace item {
+
+shared_ptr<AbstractItem> ItemInflator::Create(ItemFactory factory, Bundle b) {
+  shared_ptr<AbstractItem> item = factory.CreateItem(AbstractItem::GetType(b));
+  item.get()->Deserialize(b);
+  return item;
+}
+
+}  // namespace item
+}  // namespace notification
diff --git a/notification-ex/item_inflator.h b/notification-ex/item_inflator.h
new file mode 100644 (file)
index 0000000..b0a4122
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NOTIFICATION_EX_ITEM_INFLATOR_H_
+#define NOTIFICATION_EX_ITEM_INFLATOR_H_
+
+#include <string>
+#include <memory>
+#include <list>
+
+#include "notification-ex/abstract_item.h"
+#include "notification-ex/item_factory.h"
+
+namespace notification {
+namespace item {
+
+class EXPORT_API ItemInflator {
+ public:
+  static std::shared_ptr<AbstractItem> Create(ItemFactory factory, Bundle b);
+};
+
+}  // namespace item
+}  // namespace notification
+
+#endif  // NOTIFICATION_EX_ITEM_INFLATOR_H_
index 6376440..52c67d4 100644 (file)
@@ -13,6 +13,7 @@ BuildRequires: pkgconfig(dbus-1)
 BuildRequires: pkgconfig(dlog)
 BuildRequires: pkgconfig(aul)
 BuildRequires: pkgconfig(capi-appfw-app-control)
+BuildRequires: pkgconfig(capi-appfw-app-common)
 BuildRequires: pkgconfig(capi-appfw-package-manager)
 BuildRequires: pkgconfig(pkgmgr-info)
 BuildRequires: pkgconfig(libtzplatform-config)
@@ -56,6 +57,10 @@ make %{?jobs:-j%jobs}
 rm -rf %{buildroot}
 %make_install
 
+
+%check
+ctest --output-on-failure %{?_smp_mflags}
+
 mkdir -p %{buildroot}%{upgrade_script_path}
 cp -f scripts/505.notification_upgrade.sh %{buildroot}%{upgrade_script_path}
 
index 37b6014..86f1a0e 100644 (file)
@@ -1,4 +1,4 @@
-CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
 PROJECT(notification-ex_unittests CXX)
 
 INCLUDE(FindPkgConfig)
@@ -18,11 +18,16 @@ SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
 SET(CMAKE_CXX_FLAGS_RELEASE "-O2")
 
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../notification-ex)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../unittest/mock)
 INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../)
 
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/mock UNIT_TEST_SOURCES)
 AUX_SOURCE_DIRECTORY(src SOURCES)
+AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/../notification-ex NOTIFICATION_EX_SOURCES)
 ADD_EXECUTABLE(${PROJECT_NAME}
     ${SOURCES}
+    ${NOTIFICATION_EX_SOURCES}
+    ${UNIT_TEST_SOURCES}
 )
 
 TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${notification-ex_unittests_LDFLAGS}
@@ -33,3 +38,5 @@ TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${notification-ex_unittests_LDFLAGS}
 )
 
 INSTALL(TARGETS ${PROJECT_NAME} DESTINATION /usr/bin/)
+
+
diff --git a/unittest/mock/app_common.h b/unittest/mock/app_common.h
new file mode 100644 (file)
index 0000000..69f440c
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MOCK_APP_COMMON_H_
+#define MOCK_APP_COMMON_H_
+
+#include "mock.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+       APP_ERROR_NONE = 0, /**< Successful */
+       APP_ERROR_INVALID_PARAMETER = -22, /**< Invalid parameter */
+       APP_ERROR_OUT_OF_MEMORY = -12, /**< Out of memory */
+       APP_ERROR_INVALID_CONTEXT = -0x01100000 | 0x01, /**< Invalid application context */
+       APP_ERROR_NO_SUCH_FILE = -2, /**< No such file or directory */
+       APP_ERROR_NOT_SUPPORTED = -3, /**< Not supported (Since 4.0) */
+       APP_ERROR_ALREADY_RUNNING = -4, /**< Application is already running */
+       APP_ERROR_PERMISSION_DENIED = -5, /**< Permission denied @if MOBILE (Since 2.3.1) @endif */
+} app_error_e;
+
+DECLARE_FAKE_VALUE_FUNC(int, app_get_name, char**);
+
+#ifdef __cplusplus
+}
+#endif
+#endif  /* MOCK_APP_COMMON_H_ */
diff --git a/unittest/mock/fff.h b/unittest/mock/fff.h
new file mode 100644 (file)
index 0000000..6289a58
--- /dev/null
@@ -0,0 +1,6493 @@
+/*
+LICENSE
+
+The MIT License (MIT)
+
+Copyright (c) 2010 Michael Long
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+#ifndef FAKE_FUNCTIONS
+#define FAKE_FUNCTIONS
+
+#include <stdarg.h>
+#include <string.h> /* For memset and memcpy */
+
+#define FFF_MAX_ARGS (20u)
+#ifndef FFF_ARG_HISTORY_LEN
+    #define FFF_ARG_HISTORY_LEN (50u)
+#endif
+#ifndef FFF_CALL_HISTORY_LEN
+    #define FFF_CALL_HISTORY_LEN (50u)
+#endif
+/* -- INTERNAL HELPER MACROS -- */
+#define SET_RETURN_SEQ(FUNCNAME, ARRAY_POINTER, ARRAY_LEN) \
+    FUNCNAME##_fake.return_val_seq = ARRAY_POINTER; \
+    FUNCNAME##_fake.return_val_seq_len = ARRAY_LEN;
+#define SET_CUSTOM_FAKE_SEQ(FUNCNAME, ARRAY_POINTER, ARRAY_LEN) \
+    FUNCNAME##_fake.custom_fake_seq = ARRAY_POINTER; \
+    FUNCNAME##_fake.custom_fake_seq_len = ARRAY_LEN;
+
+/* Defining a function to reset a fake function */
+#define RESET_FAKE(FUNCNAME) { \
+    FUNCNAME##_reset(); \
+} \
+
+
+#define DECLARE_ARG(type, n, FUNCNAME) \
+    type arg##n##_val; \
+    type arg##n##_history[FFF_ARG_HISTORY_LEN];
+
+#define DECLARE_ALL_FUNC_COMMON \
+    unsigned int call_count; \
+    unsigned int arg_history_len; \
+    unsigned int arg_histories_dropped; \
+
+#define DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+    RETURN_TYPE return_val_history[FFF_ARG_HISTORY_LEN];
+
+#define SAVE_ARG(FUNCNAME, n) \
+    memcpy((void*)&FUNCNAME##_fake.arg##n##_val, (void*)&arg##n, sizeof(arg##n));
+
+#define ROOM_FOR_MORE_HISTORY(FUNCNAME) \
+    FUNCNAME##_fake.call_count < FFF_ARG_HISTORY_LEN
+
+#define SAVE_RET_HISTORY(FUNCNAME, RETVAL) \
+    if ((FUNCNAME##_fake.call_count - 1) < FFF_ARG_HISTORY_LEN) \
+        memcpy((void *)&FUNCNAME##_fake.return_val_history[FUNCNAME##_fake.call_count - 1], (const void *) &RETVAL, sizeof(RETVAL)); \
+
+#define SAVE_ARG_HISTORY(FUNCNAME, ARGN) \
+    memcpy((void*)&FUNCNAME##_fake.arg##ARGN##_history[FUNCNAME##_fake.call_count], (void*)&arg##ARGN, sizeof(arg##ARGN));
+
+#define HISTORY_DROPPED(FUNCNAME) \
+    FUNCNAME##_fake.arg_histories_dropped++
+
+#define DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+    RETURN_TYPE return_val; \
+    int return_val_seq_len; \
+    int return_val_seq_idx; \
+    RETURN_TYPE * return_val_seq; \
+
+#define DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+    int custom_fake_seq_len; \
+    int custom_fake_seq_idx; \
+
+#define INCREMENT_CALL_COUNT(FUNCNAME) \
+    FUNCNAME##_fake.call_count++
+
+#define RETURN_FAKE_RESULT(FUNCNAME) \
+    if (FUNCNAME##_fake.return_val_seq_len){ /* then its a sequence */ \
+        if(FUNCNAME##_fake.return_val_seq_idx < FUNCNAME##_fake.return_val_seq_len) { \
+            SAVE_RET_HISTORY(FUNCNAME, FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_idx]) \
+            return FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_idx++]; \
+        } \
+        SAVE_RET_HISTORY(FUNCNAME, FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_len-1]) \
+        return FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_len-1]; /* return last element */ \
+    } \
+    SAVE_RET_HISTORY(FUNCNAME, FUNCNAME##_fake.return_val) \
+    return FUNCNAME##_fake.return_val; \
+
+#ifdef __cplusplus
+    #define FFF_EXTERN_C extern "C"{
+    #define FFF_END_EXTERN_C } 
+#else  /* ansi c */
+    #define FFF_EXTERN_C 
+    #define FFF_END_EXTERN_C 
+#endif  /* cpp/ansi c */
+
+#define DEFINE_RESET_FUNCTION(FUNCNAME) \
+    void FUNCNAME##_reset(void){ \
+        memset(&FUNCNAME##_fake, 0, sizeof(FUNCNAME##_fake)); \
+        FUNCNAME##_fake.arg_history_len = FFF_ARG_HISTORY_LEN; \
+    }
+/* -- END INTERNAL HELPER MACROS -- */
+
+typedef void (*fff_function_t)(void);
+typedef struct { 
+    fff_function_t call_history[FFF_CALL_HISTORY_LEN];
+    unsigned int call_history_idx;
+} fff_globals_t;
+
+FFF_EXTERN_C
+extern fff_globals_t fff;
+FFF_END_EXTERN_C
+
+#define DEFINE_FFF_GLOBALS \
+    FFF_EXTERN_C \
+        fff_globals_t fff; \
+    FFF_END_EXTERN_C
+
+#define FFF_RESET_HISTORY() \
+    fff.call_history_idx = 0; \
+    memset(fff.call_history, 0, sizeof(fff.call_history));
+
+#define REGISTER_CALL(function) \
+    if(fff.call_history_idx < FFF_CALL_HISTORY_LEN) \
+        fff.call_history[fff.call_history_idx++] = (fff_function_t)function;
+
+#define DECLARE_FAKE_VOID_FUNC0(FUNCNAME) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(void); \
+        void(**custom_fake_seq)(void); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(void); \
+
+#define DEFINE_FAKE_VOID_FUNC0(FUNCNAME) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(void){ \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](); \
+            } \
+            else{ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(); \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC0(FUNCNAME) \
+    DECLARE_FAKE_VOID_FUNC0(FUNCNAME) \
+    DEFINE_FAKE_VOID_FUNC0(FUNCNAME) \
+
+
+#define DECLARE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0); \
+
+#define DEFINE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0); \
+            } \
+            else{ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0); \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \
+    DECLARE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \
+    DEFINE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \
+
+
+#define DECLARE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1); \
+
+#define DEFINE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1); \
+            } \
+            else{ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1); \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \
+    DECLARE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \
+    DEFINE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \
+
+
+#define DECLARE_FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \
+
+#define DEFINE_FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2); \
+            } \
+            else{ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2); \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \
+    DECLARE_FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \
+    DEFINE_FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \
+
+
+#define DECLARE_FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \
+
+#define DEFINE_FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3); \
+            } \
+            else{ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3); \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \
+    DECLARE_FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \
+    DEFINE_FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \
+
+
+#define DECLARE_FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \
+
+#define DEFINE_FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4); \
+            } \
+            else{ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4); \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \
+    DECLARE_FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \
+    DEFINE_FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \
+
+
+#define DECLARE_FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \
+
+#define DEFINE_FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5); \
+            } \
+            else{ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5); \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \
+    DECLARE_FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \
+    DEFINE_FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \
+
+
+#define DECLARE_FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \
+
+#define DEFINE_FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6); \
+            } \
+            else{ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6); \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \
+    DECLARE_FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \
+    DEFINE_FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \
+
+
+#define DECLARE_FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \
+
+#define DEFINE_FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \
+            } \
+            else{ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \
+    DECLARE_FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \
+    DEFINE_FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \
+
+
+#define DECLARE_FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \
+
+#define DEFINE_FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \
+            } \
+            else{ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \
+    DECLARE_FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \
+    DEFINE_FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \
+
+
+#define DECLARE_FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \
+
+#define DEFINE_FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \
+            } \
+            else{ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \
+    DECLARE_FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \
+    DEFINE_FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \
+
+
+#define DECLARE_FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \
+
+#define DEFINE_FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \
+            } \
+            else{ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \
+    DECLARE_FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \
+    DEFINE_FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \
+
+
+#define DECLARE_FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \
+
+#define DEFINE_FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \
+            } \
+            else{ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \
+    DECLARE_FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \
+    DEFINE_FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \
+
+
+#define DECLARE_FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \
+
+#define DEFINE_FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \
+            } \
+            else{ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \
+    DECLARE_FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \
+    DEFINE_FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \
+
+
+#define DECLARE_FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \
+
+#define DEFINE_FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \
+            } \
+            else{ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \
+    DECLARE_FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \
+    DEFINE_FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \
+
+
+#define DECLARE_FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \
+
+#define DEFINE_FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        SAVE_ARG(FUNCNAME, 14); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+            SAVE_ARG_HISTORY(FUNCNAME, 14); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \
+            } \
+            else{ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \
+    DECLARE_FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \
+    DEFINE_FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \
+
+
+#define DECLARE_FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \
+        DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \
+
+#define DEFINE_FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        SAVE_ARG(FUNCNAME, 14); \
+        SAVE_ARG(FUNCNAME, 15); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+            SAVE_ARG_HISTORY(FUNCNAME, 14); \
+            SAVE_ARG_HISTORY(FUNCNAME, 15); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \
+            } \
+            else{ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \
+    DECLARE_FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \
+    DEFINE_FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \
+
+
+#define DECLARE_FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \
+        DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \
+        DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \
+
+#define DEFINE_FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        SAVE_ARG(FUNCNAME, 14); \
+        SAVE_ARG(FUNCNAME, 15); \
+        SAVE_ARG(FUNCNAME, 16); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+            SAVE_ARG_HISTORY(FUNCNAME, 14); \
+            SAVE_ARG_HISTORY(FUNCNAME, 15); \
+            SAVE_ARG_HISTORY(FUNCNAME, 16); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \
+            } \
+            else{ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \
+    DECLARE_FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \
+    DEFINE_FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \
+
+
+#define DECLARE_FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \
+        DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \
+        DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \
+        DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \
+
+#define DEFINE_FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        SAVE_ARG(FUNCNAME, 14); \
+        SAVE_ARG(FUNCNAME, 15); \
+        SAVE_ARG(FUNCNAME, 16); \
+        SAVE_ARG(FUNCNAME, 17); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+            SAVE_ARG_HISTORY(FUNCNAME, 14); \
+            SAVE_ARG_HISTORY(FUNCNAME, 15); \
+            SAVE_ARG_HISTORY(FUNCNAME, 16); \
+            SAVE_ARG_HISTORY(FUNCNAME, 17); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \
+            } \
+            else{ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \
+    DECLARE_FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \
+    DEFINE_FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \
+
+
+#define DECLARE_FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \
+        DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \
+        DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \
+        DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \
+        DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \
+
+#define DEFINE_FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        SAVE_ARG(FUNCNAME, 14); \
+        SAVE_ARG(FUNCNAME, 15); \
+        SAVE_ARG(FUNCNAME, 16); \
+        SAVE_ARG(FUNCNAME, 17); \
+        SAVE_ARG(FUNCNAME, 18); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+            SAVE_ARG_HISTORY(FUNCNAME, 14); \
+            SAVE_ARG_HISTORY(FUNCNAME, 15); \
+            SAVE_ARG_HISTORY(FUNCNAME, 16); \
+            SAVE_ARG_HISTORY(FUNCNAME, 17); \
+            SAVE_ARG_HISTORY(FUNCNAME, 18); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \
+            } \
+            else{ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \
+    DECLARE_FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \
+    DEFINE_FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \
+
+
+#define DECLARE_FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \
+        DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \
+        DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \
+        DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \
+        DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \
+        DECLARE_ARG(ARG19_TYPE, 19, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \
+
+#define DEFINE_FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        SAVE_ARG(FUNCNAME, 14); \
+        SAVE_ARG(FUNCNAME, 15); \
+        SAVE_ARG(FUNCNAME, 16); \
+        SAVE_ARG(FUNCNAME, 17); \
+        SAVE_ARG(FUNCNAME, 18); \
+        SAVE_ARG(FUNCNAME, 19); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+            SAVE_ARG_HISTORY(FUNCNAME, 14); \
+            SAVE_ARG_HISTORY(FUNCNAME, 15); \
+            SAVE_ARG_HISTORY(FUNCNAME, 16); \
+            SAVE_ARG_HISTORY(FUNCNAME, 17); \
+            SAVE_ARG_HISTORY(FUNCNAME, 18); \
+            SAVE_ARG_HISTORY(FUNCNAME, 19); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \
+            } \
+            else{ \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \
+    DECLARE_FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \
+    DEFINE_FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(void); \
+        RETURN_TYPE(**custom_fake_seq)(void); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(void); \
+
+#define DEFINE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(void){ \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+            } \
+            else{ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(); \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \
+    DECLARE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \
+    DEFINE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0); \
+
+#define DEFINE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+            } \
+            else{ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0); \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \
+    DECLARE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \
+    DEFINE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1); \
+
+#define DEFINE_FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+            } \
+            else{ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1); \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \
+    DECLARE_FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \
+    DEFINE_FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \
+
+#define DEFINE_FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+            } \
+            else{ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2); \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \
+    DECLARE_FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \
+    DEFINE_FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \
+
+#define DEFINE_FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+            } \
+            else{ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3); \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \
+    DECLARE_FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \
+    DEFINE_FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \
+
+#define DEFINE_FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+            } \
+            else{ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4); \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \
+    DECLARE_FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \
+    DEFINE_FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \
+
+#define DEFINE_FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+            } \
+            else{ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5); \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \
+    DECLARE_FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \
+    DEFINE_FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \
+
+#define DEFINE_FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+            } \
+            else{ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6); \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \
+    DECLARE_FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \
+    DEFINE_FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \
+
+#define DEFINE_FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+            } \
+            else{ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \
+    DECLARE_FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \
+    DEFINE_FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \
+
+#define DEFINE_FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+            } \
+            else{ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \
+    DECLARE_FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \
+    DEFINE_FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \
+
+#define DEFINE_FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+            } \
+            else{ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \
+    DECLARE_FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \
+    DEFINE_FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \
+
+#define DEFINE_FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+            } \
+            else{ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \
+    DECLARE_FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \
+    DEFINE_FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \
+
+#define DEFINE_FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+            } \
+            else{ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \
+    DECLARE_FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \
+    DEFINE_FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \
+
+#define DEFINE_FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+            } \
+            else{ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \
+    DECLARE_FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \
+    DEFINE_FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \
+
+#define DEFINE_FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+            } \
+            else{ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \
+    DECLARE_FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \
+    DEFINE_FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \
+
+#define DEFINE_FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        SAVE_ARG(FUNCNAME, 14); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+            SAVE_ARG_HISTORY(FUNCNAME, 14); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+            } \
+            else{ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \
+    DECLARE_FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \
+    DEFINE_FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \
+        DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \
+
+#define DEFINE_FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        SAVE_ARG(FUNCNAME, 14); \
+        SAVE_ARG(FUNCNAME, 15); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+            SAVE_ARG_HISTORY(FUNCNAME, 14); \
+            SAVE_ARG_HISTORY(FUNCNAME, 15); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+            } \
+            else{ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \
+    DECLARE_FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \
+    DEFINE_FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \
+        DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \
+        DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \
+
+#define DEFINE_FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        SAVE_ARG(FUNCNAME, 14); \
+        SAVE_ARG(FUNCNAME, 15); \
+        SAVE_ARG(FUNCNAME, 16); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+            SAVE_ARG_HISTORY(FUNCNAME, 14); \
+            SAVE_ARG_HISTORY(FUNCNAME, 15); \
+            SAVE_ARG_HISTORY(FUNCNAME, 16); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+            } \
+            else{ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \
+    DECLARE_FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \
+    DEFINE_FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \
+        DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \
+        DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \
+        DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \
+
+#define DEFINE_FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        SAVE_ARG(FUNCNAME, 14); \
+        SAVE_ARG(FUNCNAME, 15); \
+        SAVE_ARG(FUNCNAME, 16); \
+        SAVE_ARG(FUNCNAME, 17); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+            SAVE_ARG_HISTORY(FUNCNAME, 14); \
+            SAVE_ARG_HISTORY(FUNCNAME, 15); \
+            SAVE_ARG_HISTORY(FUNCNAME, 16); \
+            SAVE_ARG_HISTORY(FUNCNAME, 17); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+            } \
+            else{ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \
+    DECLARE_FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \
+    DEFINE_FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \
+        DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \
+        DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \
+        DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \
+        DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \
+
+#define DEFINE_FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        SAVE_ARG(FUNCNAME, 14); \
+        SAVE_ARG(FUNCNAME, 15); \
+        SAVE_ARG(FUNCNAME, 16); \
+        SAVE_ARG(FUNCNAME, 17); \
+        SAVE_ARG(FUNCNAME, 18); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+            SAVE_ARG_HISTORY(FUNCNAME, 14); \
+            SAVE_ARG_HISTORY(FUNCNAME, 15); \
+            SAVE_ARG_HISTORY(FUNCNAME, 16); \
+            SAVE_ARG_HISTORY(FUNCNAME, 17); \
+            SAVE_ARG_HISTORY(FUNCNAME, 18); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+            } \
+            else{ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \
+    DECLARE_FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \
+    DEFINE_FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \
+        DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \
+        DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \
+        DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \
+        DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \
+        DECLARE_ARG(ARG19_TYPE, 19, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \
+
+#define DEFINE_FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        SAVE_ARG(FUNCNAME, 14); \
+        SAVE_ARG(FUNCNAME, 15); \
+        SAVE_ARG(FUNCNAME, 16); \
+        SAVE_ARG(FUNCNAME, 17); \
+        SAVE_ARG(FUNCNAME, 18); \
+        SAVE_ARG(FUNCNAME, 19); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+            SAVE_ARG_HISTORY(FUNCNAME, 14); \
+            SAVE_ARG_HISTORY(FUNCNAME, 15); \
+            SAVE_ARG_HISTORY(FUNCNAME, 16); \
+            SAVE_ARG_HISTORY(FUNCNAME, 17); \
+            SAVE_ARG_HISTORY(FUNCNAME, 18); \
+            SAVE_ARG_HISTORY(FUNCNAME, 19); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+            } \
+            else{ \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \
+    DECLARE_FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \
+    DEFINE_FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \
+
+
+#define DECLARE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, va_list ap); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ...); \
+
+#define DEFINE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg0); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, ap); \
+                va_end(ap); \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg0); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, ap); \
+                va_end(ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            va_list ap; \
+            va_start(ap, arg0); \
+            FUNCNAME##_fake.custom_fake(arg0, ap); \
+            va_end(ap); \
+        } \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \
+    DECLARE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \
+    DEFINE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, va_list ap); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...); \
+
+#define DEFINE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg1); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, ap); \
+                va_end(ap); \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg1); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, ap); \
+                va_end(ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            va_list ap; \
+            va_start(ap, arg1); \
+            FUNCNAME##_fake.custom_fake(arg0, arg1, ap); \
+            va_end(ap); \
+        } \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \
+    DECLARE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \
+    DEFINE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, va_list ap); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ...); \
+
+#define DEFINE_FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg2); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, ap); \
+                va_end(ap); \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg2); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, ap); \
+                va_end(ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            va_list ap; \
+            va_start(ap, arg2); \
+            FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, ap); \
+            va_end(ap); \
+        } \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \
+    DECLARE_FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \
+    DEFINE_FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, va_list ap); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ...); \
+
+#define DEFINE_FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg3); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, ap); \
+                va_end(ap); \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg3); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, ap); \
+                va_end(ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            va_list ap; \
+            va_start(ap, arg3); \
+            FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, ap); \
+            va_end(ap); \
+        } \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \
+    DECLARE_FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \
+    DEFINE_FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, va_list ap); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ...); \
+
+#define DEFINE_FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg4); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, ap); \
+                va_end(ap); \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg4); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, ap); \
+                va_end(ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            va_list ap; \
+            va_start(ap, arg4); \
+            FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, ap); \
+            va_end(ap); \
+        } \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \
+    DECLARE_FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \
+    DEFINE_FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, va_list ap); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ...); \
+
+#define DEFINE_FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg5); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, ap); \
+                va_end(ap); \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg5); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, ap); \
+                va_end(ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            va_list ap; \
+            va_start(ap, arg5); \
+            FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, ap); \
+            va_end(ap); \
+        } \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \
+    DECLARE_FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \
+    DEFINE_FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, va_list ap); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ...); \
+
+#define DEFINE_FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg6); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \
+                va_end(ap); \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg6); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \
+                va_end(ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            va_list ap; \
+            va_start(ap, arg6); \
+            FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \
+            va_end(ap); \
+        } \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \
+    DECLARE_FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \
+    DEFINE_FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, va_list ap); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ...); \
+
+#define DEFINE_FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg7); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \
+                va_end(ap); \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg7); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \
+                va_end(ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            va_list ap; \
+            va_start(ap, arg7); \
+            FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \
+            va_end(ap); \
+        } \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \
+    DECLARE_FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \
+    DEFINE_FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, va_list ap); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ...); \
+
+#define DEFINE_FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg8); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \
+                va_end(ap); \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg8); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \
+                va_end(ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            va_list ap; \
+            va_start(ap, arg8); \
+            FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \
+            va_end(ap); \
+        } \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \
+    DECLARE_FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \
+    DEFINE_FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, va_list ap); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ...); \
+
+#define DEFINE_FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg9); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \
+                va_end(ap); \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg9); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \
+                va_end(ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            va_list ap; \
+            va_start(ap, arg9); \
+            FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \
+            va_end(ap); \
+        } \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \
+    DECLARE_FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \
+    DEFINE_FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, va_list ap); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ...); \
+
+#define DEFINE_FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg10); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \
+                va_end(ap); \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg10); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \
+                va_end(ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            va_list ap; \
+            va_start(ap, arg10); \
+            FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \
+            va_end(ap); \
+        } \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \
+    DECLARE_FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \
+    DEFINE_FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, va_list ap); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ...); \
+
+#define DEFINE_FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg11); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \
+                va_end(ap); \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg11); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \
+                va_end(ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            va_list ap; \
+            va_start(ap, arg11); \
+            FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \
+            va_end(ap); \
+        } \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \
+    DECLARE_FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \
+    DEFINE_FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, va_list ap); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ...); \
+
+#define DEFINE_FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg12); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \
+                va_end(ap); \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg12); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \
+                va_end(ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            va_list ap; \
+            va_start(ap, arg12); \
+            FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \
+            va_end(ap); \
+        } \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \
+    DECLARE_FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \
+    DEFINE_FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, va_list ap); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ...); \
+
+#define DEFINE_FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg13); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \
+                va_end(ap); \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg13); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \
+                va_end(ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            va_list ap; \
+            va_start(ap, arg13); \
+            FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \
+            va_end(ap); \
+        } \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \
+    DECLARE_FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \
+    DEFINE_FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, va_list ap); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ...); \
+
+#define DEFINE_FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        SAVE_ARG(FUNCNAME, 14); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+            SAVE_ARG_HISTORY(FUNCNAME, 14); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg14); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \
+                va_end(ap); \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg14); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \
+                va_end(ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            va_list ap; \
+            va_start(ap, arg14); \
+            FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \
+            va_end(ap); \
+        } \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \
+    DECLARE_FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \
+    DEFINE_FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \
+        DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, va_list ap); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ...); \
+
+#define DEFINE_FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        SAVE_ARG(FUNCNAME, 14); \
+        SAVE_ARG(FUNCNAME, 15); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+            SAVE_ARG_HISTORY(FUNCNAME, 14); \
+            SAVE_ARG_HISTORY(FUNCNAME, 15); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg15); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \
+                va_end(ap); \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg15); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \
+                va_end(ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            va_list ap; \
+            va_start(ap, arg15); \
+            FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \
+            va_end(ap); \
+        } \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \
+    DECLARE_FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \
+    DEFINE_FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \
+        DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \
+        DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, va_list ap); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ...); \
+
+#define DEFINE_FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        SAVE_ARG(FUNCNAME, 14); \
+        SAVE_ARG(FUNCNAME, 15); \
+        SAVE_ARG(FUNCNAME, 16); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+            SAVE_ARG_HISTORY(FUNCNAME, 14); \
+            SAVE_ARG_HISTORY(FUNCNAME, 15); \
+            SAVE_ARG_HISTORY(FUNCNAME, 16); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg16); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \
+                va_end(ap); \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg16); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \
+                va_end(ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            va_list ap; \
+            va_start(ap, arg16); \
+            FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \
+            va_end(ap); \
+        } \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \
+    DECLARE_FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \
+    DEFINE_FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \
+        DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \
+        DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \
+        DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, va_list ap); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ...); \
+
+#define DEFINE_FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        SAVE_ARG(FUNCNAME, 14); \
+        SAVE_ARG(FUNCNAME, 15); \
+        SAVE_ARG(FUNCNAME, 16); \
+        SAVE_ARG(FUNCNAME, 17); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+            SAVE_ARG_HISTORY(FUNCNAME, 14); \
+            SAVE_ARG_HISTORY(FUNCNAME, 15); \
+            SAVE_ARG_HISTORY(FUNCNAME, 16); \
+            SAVE_ARG_HISTORY(FUNCNAME, 17); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg17); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \
+                va_end(ap); \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg17); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \
+                va_end(ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            va_list ap; \
+            va_start(ap, arg17); \
+            FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \
+            va_end(ap); \
+        } \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \
+    DECLARE_FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \
+    DEFINE_FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \
+        DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \
+        DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \
+        DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \
+        DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, va_list ap); \
+        void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ...); \
+
+#define DEFINE_FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        SAVE_ARG(FUNCNAME, 14); \
+        SAVE_ARG(FUNCNAME, 15); \
+        SAVE_ARG(FUNCNAME, 16); \
+        SAVE_ARG(FUNCNAME, 17); \
+        SAVE_ARG(FUNCNAME, 18); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+            SAVE_ARG_HISTORY(FUNCNAME, 14); \
+            SAVE_ARG_HISTORY(FUNCNAME, 15); \
+            SAVE_ARG_HISTORY(FUNCNAME, 16); \
+            SAVE_ARG_HISTORY(FUNCNAME, 17); \
+            SAVE_ARG_HISTORY(FUNCNAME, 18); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg18); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \
+                va_end(ap); \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg18); \
+                FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \
+                va_end(ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            va_list ap; \
+            va_start(ap, arg18); \
+            FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \
+            va_end(ap); \
+        } \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \
+    DECLARE_FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \
+    DEFINE_FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, va_list ap); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ...); \
+
+#define DEFINE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg0); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg0); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            RETURN_TYPE ret; \
+            va_list ap; \
+            va_start(ap, arg0); \
+            ret = FUNCNAME##_fake.custom_fake(arg0, ap); \
+            va_end(ap); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \
+    DECLARE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \
+    DEFINE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, va_list ap); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...); \
+
+#define DEFINE_FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg1); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg1); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            RETURN_TYPE ret; \
+            va_list ap; \
+            va_start(ap, arg1); \
+            ret = FUNCNAME##_fake.custom_fake(arg0, arg1, ap); \
+            va_end(ap); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \
+    DECLARE_FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \
+    DEFINE_FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, va_list ap); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ...); \
+
+#define DEFINE_FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg2); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg2); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            RETURN_TYPE ret; \
+            va_list ap; \
+            va_start(ap, arg2); \
+            ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, ap); \
+            va_end(ap); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \
+    DECLARE_FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \
+    DEFINE_FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, va_list ap); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ...); \
+
+#define DEFINE_FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg3); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg3); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            RETURN_TYPE ret; \
+            va_list ap; \
+            va_start(ap, arg3); \
+            ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, ap); \
+            va_end(ap); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \
+    DECLARE_FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \
+    DEFINE_FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, va_list ap); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ...); \
+
+#define DEFINE_FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg4); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg4); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            RETURN_TYPE ret; \
+            va_list ap; \
+            va_start(ap, arg4); \
+            ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, ap); \
+            va_end(ap); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \
+    DECLARE_FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \
+    DEFINE_FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, va_list ap); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ...); \
+
+#define DEFINE_FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg5); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg5); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            RETURN_TYPE ret; \
+            va_list ap; \
+            va_start(ap, arg5); \
+            ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, ap); \
+            va_end(ap); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \
+    DECLARE_FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \
+    DEFINE_FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, va_list ap); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ...); \
+
+#define DEFINE_FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg6); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg6); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            RETURN_TYPE ret; \
+            va_list ap; \
+            va_start(ap, arg6); \
+            ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \
+            va_end(ap); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \
+    DECLARE_FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \
+    DEFINE_FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, va_list ap); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ...); \
+
+#define DEFINE_FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg7); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg7); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            RETURN_TYPE ret; \
+            va_list ap; \
+            va_start(ap, arg7); \
+            ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \
+            va_end(ap); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \
+    DECLARE_FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \
+    DEFINE_FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, va_list ap); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ...); \
+
+#define DEFINE_FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg8); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg8); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            RETURN_TYPE ret; \
+            va_list ap; \
+            va_start(ap, arg8); \
+            ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \
+            va_end(ap); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \
+    DECLARE_FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \
+    DEFINE_FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, va_list ap); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ...); \
+
+#define DEFINE_FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg9); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg9); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            RETURN_TYPE ret; \
+            va_list ap; \
+            va_start(ap, arg9); \
+            ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \
+            va_end(ap); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \
+    DECLARE_FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \
+    DEFINE_FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, va_list ap); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ...); \
+
+#define DEFINE_FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg10); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg10); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            RETURN_TYPE ret; \
+            va_list ap; \
+            va_start(ap, arg10); \
+            ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \
+            va_end(ap); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \
+    DECLARE_FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \
+    DEFINE_FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, va_list ap); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ...); \
+
+#define DEFINE_FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg11); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg11); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            RETURN_TYPE ret; \
+            va_list ap; \
+            va_start(ap, arg11); \
+            ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \
+            va_end(ap); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \
+    DECLARE_FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \
+    DEFINE_FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, va_list ap); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ...); \
+
+#define DEFINE_FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg12); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg12); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            RETURN_TYPE ret; \
+            va_list ap; \
+            va_start(ap, arg12); \
+            ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \
+            va_end(ap); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \
+    DECLARE_FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \
+    DEFINE_FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, va_list ap); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ...); \
+
+#define DEFINE_FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg13); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg13); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            RETURN_TYPE ret; \
+            va_list ap; \
+            va_start(ap, arg13); \
+            ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \
+            va_end(ap); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \
+    DECLARE_FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \
+    DEFINE_FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, va_list ap); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ...); \
+
+#define DEFINE_FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        SAVE_ARG(FUNCNAME, 14); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+            SAVE_ARG_HISTORY(FUNCNAME, 14); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg14); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg14); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            RETURN_TYPE ret; \
+            va_list ap; \
+            va_start(ap, arg14); \
+            ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \
+            va_end(ap); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \
+    DECLARE_FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \
+    DEFINE_FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \
+        DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, va_list ap); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ...); \
+
+#define DEFINE_FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        SAVE_ARG(FUNCNAME, 14); \
+        SAVE_ARG(FUNCNAME, 15); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+            SAVE_ARG_HISTORY(FUNCNAME, 14); \
+            SAVE_ARG_HISTORY(FUNCNAME, 15); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg15); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg15); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            RETURN_TYPE ret; \
+            va_list ap; \
+            va_start(ap, arg15); \
+            ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \
+            va_end(ap); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \
+    DECLARE_FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \
+    DEFINE_FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \
+        DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \
+        DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, va_list ap); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ...); \
+
+#define DEFINE_FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        SAVE_ARG(FUNCNAME, 14); \
+        SAVE_ARG(FUNCNAME, 15); \
+        SAVE_ARG(FUNCNAME, 16); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+            SAVE_ARG_HISTORY(FUNCNAME, 14); \
+            SAVE_ARG_HISTORY(FUNCNAME, 15); \
+            SAVE_ARG_HISTORY(FUNCNAME, 16); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg16); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg16); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            RETURN_TYPE ret; \
+            va_list ap; \
+            va_start(ap, arg16); \
+            ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \
+            va_end(ap); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \
+    DECLARE_FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \
+    DEFINE_FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \
+        DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \
+        DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \
+        DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, va_list ap); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ...); \
+
+#define DEFINE_FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        SAVE_ARG(FUNCNAME, 14); \
+        SAVE_ARG(FUNCNAME, 15); \
+        SAVE_ARG(FUNCNAME, 16); \
+        SAVE_ARG(FUNCNAME, 17); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+            SAVE_ARG_HISTORY(FUNCNAME, 14); \
+            SAVE_ARG_HISTORY(FUNCNAME, 15); \
+            SAVE_ARG_HISTORY(FUNCNAME, 16); \
+            SAVE_ARG_HISTORY(FUNCNAME, 17); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg17); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg17); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            RETURN_TYPE ret; \
+            va_list ap; \
+            va_start(ap, arg17); \
+            ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \
+            va_end(ap); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \
+    DECLARE_FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \
+    DEFINE_FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \
+
+
+#define DECLARE_FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \
+    typedef struct FUNCNAME##_Fake { \
+        DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \
+        DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \
+        DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \
+        DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \
+        DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \
+        DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \
+        DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \
+        DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \
+        DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \
+        DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \
+        DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \
+        DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \
+        DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \
+        DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \
+        DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \
+        DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \
+        DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \
+        DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \
+        DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \
+        DECLARE_ALL_FUNC_COMMON \
+        DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \
+        DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \
+        DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \
+        RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, va_list ap); \
+        RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ...); \
+
+#define DEFINE_FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ...){ \
+        SAVE_ARG(FUNCNAME, 0); \
+        SAVE_ARG(FUNCNAME, 1); \
+        SAVE_ARG(FUNCNAME, 2); \
+        SAVE_ARG(FUNCNAME, 3); \
+        SAVE_ARG(FUNCNAME, 4); \
+        SAVE_ARG(FUNCNAME, 5); \
+        SAVE_ARG(FUNCNAME, 6); \
+        SAVE_ARG(FUNCNAME, 7); \
+        SAVE_ARG(FUNCNAME, 8); \
+        SAVE_ARG(FUNCNAME, 9); \
+        SAVE_ARG(FUNCNAME, 10); \
+        SAVE_ARG(FUNCNAME, 11); \
+        SAVE_ARG(FUNCNAME, 12); \
+        SAVE_ARG(FUNCNAME, 13); \
+        SAVE_ARG(FUNCNAME, 14); \
+        SAVE_ARG(FUNCNAME, 15); \
+        SAVE_ARG(FUNCNAME, 16); \
+        SAVE_ARG(FUNCNAME, 17); \
+        SAVE_ARG(FUNCNAME, 18); \
+        if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \
+            SAVE_ARG_HISTORY(FUNCNAME, 0); \
+            SAVE_ARG_HISTORY(FUNCNAME, 1); \
+            SAVE_ARG_HISTORY(FUNCNAME, 2); \
+            SAVE_ARG_HISTORY(FUNCNAME, 3); \
+            SAVE_ARG_HISTORY(FUNCNAME, 4); \
+            SAVE_ARG_HISTORY(FUNCNAME, 5); \
+            SAVE_ARG_HISTORY(FUNCNAME, 6); \
+            SAVE_ARG_HISTORY(FUNCNAME, 7); \
+            SAVE_ARG_HISTORY(FUNCNAME, 8); \
+            SAVE_ARG_HISTORY(FUNCNAME, 9); \
+            SAVE_ARG_HISTORY(FUNCNAME, 10); \
+            SAVE_ARG_HISTORY(FUNCNAME, 11); \
+            SAVE_ARG_HISTORY(FUNCNAME, 12); \
+            SAVE_ARG_HISTORY(FUNCNAME, 13); \
+            SAVE_ARG_HISTORY(FUNCNAME, 14); \
+            SAVE_ARG_HISTORY(FUNCNAME, 15); \
+            SAVE_ARG_HISTORY(FUNCNAME, 16); \
+            SAVE_ARG_HISTORY(FUNCNAME, 17); \
+            SAVE_ARG_HISTORY(FUNCNAME, 18); \
+        } \
+        else{ \
+            HISTORY_DROPPED(FUNCNAME); \
+        } \
+        INCREMENT_CALL_COUNT(FUNCNAME); \
+        REGISTER_CALL(FUNCNAME); \
+        if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \
+            if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \
+                va_list ap; \
+                va_start(ap, arg18); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+            } \
+            else{ \
+                va_list ap; \
+                va_start(ap, arg18); \
+                RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \
+                SAVE_RET_HISTORY(FUNCNAME, ret); \
+                va_end(ap); \
+                return ret; \
+                return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \
+            } \
+        } \
+        if(FUNCNAME##_fake.custom_fake){ \
+            RETURN_TYPE ret; \
+            va_list ap; \
+            va_start(ap, arg18); \
+            ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \
+            va_end(ap); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        RETURN_FAKE_RESULT(FUNCNAME) \
+    } \
+    DEFINE_RESET_FUNCTION(FUNCNAME) \
+
+#define FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \
+    DECLARE_FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \
+    DEFINE_FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \
+
+/* MSVC expand macro fix */
+#define EXPAND(x) x
+
+#define PP_NARG_MINUS2(...)   EXPAND(PP_NARG_MINUS2_(__VA_ARGS__, PP_RSEQ_N_MINUS2()))
+
+#define PP_NARG_MINUS2_(...)   EXPAND(PP_ARG_MINUS2_N(__VA_ARGS__))
+
+#define PP_ARG_MINUS2_N(returnVal,  _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...)   N
+
+#define PP_RSEQ_N_MINUS2()   20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
+
+#define PP_NARG_MINUS1(...)   EXPAND(PP_NARG_MINUS1_(__VA_ARGS__, PP_RSEQ_N_MINUS1()))
+
+#define PP_NARG_MINUS1_(...)   EXPAND(PP_ARG_MINUS1_N(__VA_ARGS__))
+
+#define PP_ARG_MINUS1_N( _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...)   N
+
+#define PP_RSEQ_N_MINUS1()   20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
+
+
+
+/* DECLARE AND DEFINE FAKE FUNCTIONS - PLACE IN TEST FILES */
+
+#define FAKE_VALUE_FUNC(...)     EXPAND(FUNC_VALUE_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__))
+
+#define FUNC_VALUE_(N,...)     EXPAND(FUNC_VALUE_N(N,__VA_ARGS__))
+
+#define FUNC_VALUE_N(N,...)     EXPAND(FAKE_VALUE_FUNC ## N(__VA_ARGS__))
+
+
+#define FAKE_VOID_FUNC(...)     EXPAND(FUNC_VOID_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__))
+
+#define FUNC_VOID_(N,...)     EXPAND(FUNC_VOID_N(N,__VA_ARGS__))
+
+#define FUNC_VOID_N(N,...)     EXPAND(FAKE_VOID_FUNC ## N(__VA_ARGS__))
+
+
+#define FAKE_VALUE_FUNC_VARARG(...)     EXPAND(FUNC_VALUE_VARARG_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__))
+
+#define FUNC_VALUE_VARARG_(N,...)     EXPAND(FUNC_VALUE_VARARG_N(N,__VA_ARGS__))
+
+#define FUNC_VALUE_VARARG_N(N,...)     EXPAND(FAKE_VALUE_FUNC ## N ## _VARARG(__VA_ARGS__))
+
+
+#define FAKE_VOID_FUNC_VARARG(...)     EXPAND(FUNC_VOID_VARARG_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__))
+
+#define FUNC_VOID_VARARG_(N,...)     EXPAND(FUNC_VOID_VARARG_N(N,__VA_ARGS__))
+
+#define FUNC_VOID_VARARG_N(N,...)     EXPAND(FAKE_VOID_FUNC ## N ## _VARARG(__VA_ARGS__))
+
+
+
+/* DECLARE FAKE FUNCTIONS - PLACE IN HEADER FILES */
+
+#define DECLARE_FAKE_VALUE_FUNC(...)     EXPAND(DECLARE_FUNC_VALUE_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__))
+
+#define DECLARE_FUNC_VALUE_(N,...)     EXPAND(DECLARE_FUNC_VALUE_N(N,__VA_ARGS__))
+
+#define DECLARE_FUNC_VALUE_N(N,...)     EXPAND(DECLARE_FAKE_VALUE_FUNC ## N(__VA_ARGS__))
+
+
+#define DECLARE_FAKE_VOID_FUNC(...)     EXPAND(DECLARE_FUNC_VOID_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__))
+
+#define DECLARE_FUNC_VOID_(N,...)     EXPAND(DECLARE_FUNC_VOID_N(N,__VA_ARGS__))
+
+#define DECLARE_FUNC_VOID_N(N,...)     EXPAND(DECLARE_FAKE_VOID_FUNC ## N(__VA_ARGS__))
+
+
+#define DECLARE_FAKE_VALUE_FUNC_VARARG(...)     EXPAND(DECLARE_FUNC_VALUE_VARARG_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__))
+
+#define DECLARE_FUNC_VALUE_VARARG_(N,...)     EXPAND(DECLARE_FUNC_VALUE_VARARG_N(N,__VA_ARGS__))
+
+#define DECLARE_FUNC_VALUE_VARARG_N(N,...)     EXPAND(DECLARE_FAKE_VALUE_FUNC ## N ## _VARARG(__VA_ARGS__))
+
+
+#define DECLARE_FAKE_VOID_FUNC_VARARG(...)     EXPAND(DECLARE_FUNC_VOID_VARARG_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__))
+
+#define DECLARE_FUNC_VOID_VARARG_(N,...)     EXPAND(DECLARE_FUNC_VOID_VARARG_N(N,__VA_ARGS__))
+
+#define DECLARE_FUNC_VOID_VARARG_N(N,...)     EXPAND(DECLARE_FAKE_VOID_FUNC ## N ## _VARARG(__VA_ARGS__))
+
+
+
+/* DEFINE FAKE FUNCTIONS - PLACE IN SOURCE FILES */
+
+#define DEFINE_FAKE_VALUE_FUNC(...)     EXPAND(DEFINE_FUNC_VALUE_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__))
+
+#define DEFINE_FUNC_VALUE_(N,...)     EXPAND(DEFINE_FUNC_VALUE_N(N,__VA_ARGS__))
+
+#define DEFINE_FUNC_VALUE_N(N,...)     EXPAND(DEFINE_FAKE_VALUE_FUNC ## N(__VA_ARGS__))
+
+
+#define DEFINE_FAKE_VOID_FUNC(...)     EXPAND(DEFINE_FUNC_VOID_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__))
+
+#define DEFINE_FUNC_VOID_(N,...)     EXPAND(DEFINE_FUNC_VOID_N(N,__VA_ARGS__))
+
+#define DEFINE_FUNC_VOID_N(N,...)     EXPAND(DEFINE_FAKE_VOID_FUNC ## N(__VA_ARGS__))
+
+
+#define DEFINE_FAKE_VALUE_FUNC_VARARG(...)     EXPAND(DEFINE_FUNC_VALUE_VARARG_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__))
+
+#define DEFINE_FUNC_VALUE_VARARG_(N,...)     EXPAND(DEFINE_FUNC_VALUE_VARARG_N(N,__VA_ARGS__))
+
+#define DEFINE_FUNC_VALUE_VARARG_N(N,...)     EXPAND(DEFINE_FAKE_VALUE_FUNC ## N ## _VARARG(__VA_ARGS__))
+
+
+#define DEFINE_FAKE_VOID_FUNC_VARARG(...)     EXPAND(DEFINE_FUNC_VOID_VARARG_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__))
+
+#define DEFINE_FUNC_VOID_VARARG_(N,...)     EXPAND(DEFINE_FUNC_VOID_VARARG_N(N,__VA_ARGS__))
+
+#define DEFINE_FUNC_VOID_VARARG_N(N,...)     EXPAND(DEFINE_FAKE_VOID_FUNC ## N ## _VARARG(__VA_ARGS__))
+
+
+
+
+#endif /* FAKE_FUNCTIONS */
diff --git a/unittest/mock/mock.cc b/unittest/mock/mock.cc
new file mode 100644 (file)
index 0000000..687ad67
--- /dev/null
@@ -0,0 +1,10 @@
+// Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include "app_common.h"
+#include "mock.h"
+
+DEFINE_FFF_GLOBALS;
+
+DEFINE_FAKE_VALUE_FUNC(int, app_get_name, char**);
\ No newline at end of file
diff --git a/unittest/mock/mock.h b/unittest/mock/mock.h
new file mode 100644 (file)
index 0000000..23adbd0
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MOCK_MOCK_H__
+#define MOCK_MOCK_H__
+
+#include "fff.h"
+
+#endif // MOCK_MOCK_H__
diff --git a/unittest/src/test_button_item.cc b/unittest/src/test_button_item.cc
new file mode 100644 (file)
index 0000000..7a4ac00
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include <gmock/gmock.h>
+
+#include "notification-ex/button_item.h"
+#include "notification-ex/item_inflator.h"
+
+using namespace notification::item;
+using namespace std;
+
+namespace {
+
+class ButtonItemTest : public ::testing::Test {
+ protected:
+  void SetUp() override {}
+  void TearDown() override {}
+};
+
+TEST_F(ButtonItemTest, SerializeDeserializeGetTitle) {
+  ButtonItem item("title");
+  Bundle b = item.Serialize();
+  ItemFactory factory;
+  shared_ptr<AbstractItem> gen_item = ItemInflator::Create(factory, b);
+  ASSERT_EQ(gen_item.get()->GetType(), item.GetType());
+
+  ButtonItem* gen_btn = static_cast<ButtonItem*>(gen_item.get());
+  ASSERT_EQ(item.GetTitle(), gen_btn->GetTitle());
+}
+
+}  // namespace
diff --git a/unittest/src/test_group_item.cc b/unittest/src/test_group_item.cc
new file mode 100644 (file)
index 0000000..67fb14d
--- /dev/null
@@ -0,0 +1,99 @@
+// Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include <gmock/gmock.h>
+
+#include "notification-ex/group_item.h"
+#include "notification-ex/button_item.h"
+#include "notification-ex/item_inflator.h"
+#include "unittest/mock/app_common.h"
+
+using namespace notification::item;
+using namespace std;
+
+namespace {
+
+class GroupItemTest : public ::testing::Test {
+ protected:
+  void SetUp() override {}
+  void TearDown() override {}
+};
+
+TEST_F(GroupItemTest, AddChild) {
+  GroupItem item("GROUP1");
+  item.AddChild(std::make_shared<ButtonItem>("btn1", "test1"));
+  item.AddChild(std::make_shared<ButtonItem>("btn2", "test2"));
+  ASSERT_EQ(item.GetChildren().size(), 2);
+}
+
+TEST_F(GroupItemTest, RemoveChild) {
+  GroupItem item("GROUP1");
+  item.AddChild(std::make_shared<ButtonItem>("btn1", "test1"));
+  item.AddChild(std::make_shared<ButtonItem>("btn2", "test2"));
+  ASSERT_EQ(item.GetChildren().size(), 2);
+
+  item.RemoveChild("btn1");
+  ASSERT_EQ(item.GetChildren().size(), 1);
+}
+
+TEST_F(GroupItemTest, SerializeDeserialize) {
+  GroupItem item("GROUP1");
+  item.AddChild(std::make_shared<ButtonItem>("btn1", "test1"));
+  item.AddChild(std::make_shared<ButtonItem>("btn2", "test2"));
+
+  Bundle b = item.Serialize();
+  ItemFactory factory;
+  shared_ptr<AbstractItem> gen_item = ItemInflator::Create(factory, b);
+  ASSERT_EQ(gen_item.get()->GetType(), item.GetType());
+
+  GroupItem* gen_group = static_cast<GroupItem*>(gen_item.get());
+  list<shared_ptr<AbstractItem>> gen_children_list = gen_group->GetChildren();
+  list<shared_ptr<AbstractItem>> origin_children_list = item.GetChildren();
+
+  list<shared_ptr<AbstractItem>>::iterator it = origin_children_list.begin();
+  for (auto& i : gen_children_list) {
+    ASSERT_EQ(i.get()->GetType(), (*it).get()->GetType());
+    if (i.get()->GetType() == AbstractItem::Button) {
+      ButtonItem* btn1 = static_cast<ButtonItem*>(i.get());
+      ButtonItem* btn2 = static_cast<ButtonItem*>((*it).get());
+      ASSERT_EQ(btn1->GetTitle(), btn2->GetTitle());
+    }
+    it++;
+  }
+  ASSERT_EQ(item.GetChildren().size(), 2);
+}
+
+TEST_F(GroupItemTest, FindByID) {
+  GroupItem item("GROUP1");
+  item.AddChild(std::make_shared<ButtonItem>("btn1", "test1"));
+  item.AddChild(std::make_shared<ButtonItem>("btn2", "test2"));
+  ASSERT_EQ(item.GetChildren().size(), 2);
+
+  shared_ptr<AbstractItem> child = item.FindByID("btn2");
+  ButtonItem* btn = static_cast<ButtonItem*>(child.get());
+  ASSERT_EQ(btn->GetTitle(), "test2");
+}
+
+int __fake_app_get_name(char** app_name) {
+  *app_name = (char*)"unittest_appname";
+  return 0;
+}
+
+TEST_F(GroupItemTest, GetAppLabel) {
+  app_get_name_fake.custom_fake = __fake_app_get_name;
+
+  GroupItem item("GROUP1");
+  string app_label = item.GetAppLabel();
+
+  ASSERT_EQ(app_label, "unittest_appname");
+}
+
+TEST_F(GroupItemTest, SetDirection) {
+  GroupItem item("GROUP1");
+  item.SetDirection(true);
+
+  ASSERT_TRUE(item.IsVertical());
+}
+
+}  // namespace