]> git.mdlowis.com Git - proto/aos.git/commitdiff
added unit tests for window manager
authorMichael D. Lowis <mike@mdlowis.com>
Sun, 21 May 2023 02:45:22 +0000 (22:45 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Sun, 21 May 2023 02:45:22 +0000 (22:45 -0400)
bin/winmgr/anvil.h
bin/winmgr/client.c
bin/winmgr/event.c [new file with mode: 0644]
bin/winmgr/winmgr.c
config.mk
inc/fakes/X11.h [new file with mode: 0644]
inc/fakes/fff.h [new file with mode: 0644]
test/winmgr/main.c [new file with mode: 0644]

index 0b0cdb4ef0bc31deaeba1ec7b4d8390e551c6d04..bbac50eb83df0faa561404a3ed537b3e465851eb 100644 (file)
@@ -39,6 +39,9 @@
 #define FRAME_HEIGHT_SUM (2*BORDER_WIDTH + TITLE_HEIGHT)
 #define FRAME_WIDTH_SUM (2*BORDER_WIDTH)
 
+#define NUM_BITMAP_CELLS (MAX_CLIENTS / sizeof(unsigned long) + 1)
+#define CELL_IS_FULL ((unsigned long)-1)
+
 #define min(a,b) (a < b ? a : b)
 #define max(a,b) (a > b ? a : b)
 
@@ -148,6 +151,18 @@ typedef struct {
 /* anvil.c */
 extern XConf X;
 
+void Event_Map(Window w, XWindowAttributes* attr);
+void Event_Unmap(Window w, Window parent);
+void Event_Destroy(Window w);
+void Event_Configure(Window w, XWindowChanges* wc, unsigned long mask);
+void Event_Activate(Window w);
+void Event_PropertyChange(Window w);
+void Event_Enter(Window w);
+void Event_Redraw(Window w);
+void Event_ButtonPress(Window w, int win_x, int win_y, int root_x, int root_y);
+void Event_ButtonRelease(Window w);
+void Event_ButtonMotion(Window w);
+void Event_KeyPress(Window w);
 
 void Client_InitExistingWindows(void);
 Client* Client_Find(Window win);
index a0e9c7051f5b177cd92fa6a73ecf6de3db161509..3dcb394807a23a40bd175e46ae573326eea3d586 100644 (file)
@@ -1,13 +1,10 @@
 #include "anvil.h"
 
-#define NUM_BITMAP_CELLS (MAX_CLIENTS / sizeof(unsigned long) + 1)
-#define CELL_IS_FULL ((unsigned long)-1)
-
 /* Client allocation bitmap */
-static unsigned long Client_Bitmap[NUM_BITMAP_CELLS];
+unsigned long Client_Bitmap[NUM_BITMAP_CELLS];
 
 /* Client allocation buffer */
-static Client Client_Buffer[MAX_CLIENTS];
+Client Client_Buffer[MAX_CLIENTS];
 
 /* The currently focused client */
 Client* Focused = NULL;
@@ -53,7 +50,6 @@ Client* Client_Find(Window win)
 Client* Client_Add(Window win, XWindowAttributes* attr)
 {
     Client* c = NULL;
-
     for (int i = 0; i < NUM_BITMAP_CELLS; i++)
     {
         if (Client_Bitmap[i] != CELL_IS_FULL)
@@ -97,13 +93,19 @@ Client* Client_Add(Window win, XWindowAttributes* attr)
 
 void Client_Del(Client* client)
 {
-        /* cleanup stuff here... */
-        memset(client, 0, sizeof(Client));
-        /* now deallocate it */
-        unsigned long  client_index = (client - &Client_Buffer[0]) / sizeof(Client);
-        unsigned long cell = client_index / sizeof(unsigned long);
-        unsigned long bit = client_index % sizeof(unsigned long);
-        Client_Bitmap[cell] &= ~(1 << bit);
+    /* reverse the add operations */
+    XReparentWindow(X.disp, client->win, X.root, 0, 0);
+    XRemoveFromSaveSet(X.disp, client->win);
+    XDestroyWindow(X.disp, client->frame);
+
+    /* cleanup stuff here... */
+    memset(client, 0, sizeof(Client));
+
+    /* now deallocate it */
+    unsigned long  client_index = (client - &Client_Buffer[0]);
+    unsigned long cell = client_index / sizeof(unsigned long);
+    unsigned long bit = client_index % sizeof(unsigned long);
+    Client_Bitmap[cell] &= ~(1 << bit);
 }
 
 void Client_AdjustSize(Client* client)
diff --git a/bin/winmgr/event.c b/bin/winmgr/event.c
new file mode 100644 (file)
index 0000000..42dead5
--- /dev/null
@@ -0,0 +1,144 @@
+#include "anvil.h"
+
+void Event_Map(Window w, XWindowAttributes* attr)
+{
+    if (!Client_Find(w))
+    {
+        if (!attr->override_redirect)
+        {
+            Client_Add(w, attr);
+        }
+    }
+}
+
+void Event_Unmap(Window w, Window parent)
+{
+    Client* client = Client_Find(w);
+    if (client)
+    {
+//        if (parent == X.root)
+//        {
+            Client_Del(client);
+//        }
+//        else if ( !(client->flags & F_SHADED) )
+//        {
+//            client->flags |= F_WITHDRAWN;
+//            XUnmapWindow(X.disp, client->frame);
+//        }
+    }
+}
+
+void Event_Destroy(Window w)
+{
+    Client* client = Client_Find(w);
+    if (client)
+    {
+        Client_Del(client);
+    }
+}
+
+void Event_Configure(Window w, XWindowChanges* wc, unsigned long mask)
+{
+    Client* client = Client_Find(w);
+    if (client)
+    {
+        /* only allow floating clients to resize on their own */
+        if ((client->win == w) && !client->column)
+        {
+            client->w = wc->width + FRAME_WIDTH_SUM;
+            client->h = wc->height + FRAME_HEIGHT_SUM;
+            Client_AdjustSize(client);
+            if (X.mode == M_RESIZE && Focused == client)
+            {
+                Mouse_ToCorner(client);
+            }
+        }
+    }
+    else
+    {
+        XConfigureWindow(X.disp, w, mask, wc);
+    }
+}
+
+void Event_Activate(Window w)
+{
+    Client_SetActive(w);
+}
+
+void Event_PropertyChange(Window w)
+{
+    Client* client = Client_Find(w);
+    if (client)
+    {
+        Client_ReadProps(client);
+        Client_Draw(client);
+    }
+}
+
+void Event_Enter(Window w)
+{
+    Client* client = Client_Find(w);
+    if (client)
+    {
+        Client_Focus(client);
+    }
+}
+
+void Event_Redraw(Window w)
+{
+    Client* client = Client_Find(w);
+    if (client)
+    {
+        Client_Draw(client);
+    }
+}
+
+void Event_ButtonPress(Window w, int win_x, int win_y, int root_x, int root_y)
+{
+    Client* client = Client_Find(w);
+    if (client && (client->frame == w))
+    {
+        if (win_y < MIN_HEIGHT)
+        {
+            X.edge = E_TOP;
+        }
+        else if (root_y > (client->y + client->h - BORDER_WIDTH))
+        {
+            X.edge = E_BOTTOM;
+        }
+        else if (win_x < BORDER_WIDTH)
+        {
+            X.edge = E_LEFT;
+        }
+        else if (root_x > (client->x + client->w - BORDER_WIDTH))
+        {
+            X.edge = E_RIGHT;
+        }
+        else
+        {
+            X.edge = E_NONE;
+        }
+//        Mouse_Down(ev, client);
+    }
+}
+
+void Event_ButtonRelease(Window w)
+{
+    Client* client = Client_Find(w);
+    if (client && (client->frame == w))
+    {
+//        Mouse_Up(ev, client);
+    }
+    X.mode = M_IDLE;
+    XUngrabPointer(X.disp, CurrentTime);
+}
+
+void Event_ButtonMotion(Window w)
+{
+    Client* client = Client_Find(w);
+    if (client && (client->frame == w))
+    {
+//        Mouse_Drag(ev, client);
+    }
+}
+
index 878bc39bfe7fc966b9eec0fff89b6974c1b4d361..ec3ad8b95eb5d6ea86a113d06a0ae0a5759dbe6b 100644 (file)
@@ -19,15 +19,8 @@ static void xmaprequest(XEvent* e)
     XMapRequestEvent* ev = &(e->xmaprequest);
     printf("MAP(w: 0x%lx)\n", ev->window);
     XWindowAttributes attr;
-
-    /* if no record of this window exists, add it to our managed list */
-    if (!Client_Find(ev->window))
-    {
-        if (XGetWindowAttributes(X.disp, ev->window, &attr) && !attr.override_redirect)
-        {
-            Client_Add(ev->window, &attr);
-        }
-    }
+    XGetWindowAttributes(X.disp, ev->window, &attr);
+    Event_Map(ev->window, &attr);
 }
 
 /* Handle unmap events for window we manage.
@@ -39,20 +32,7 @@ static void xunmapnotify(XEvent* e)
 {
     XUnmapEvent* ev = &(e->xunmap);
     printf("UNMAP(e: 0x%lx w: 0x%lx %d)\n", ev->event, ev->window, ev->from_configure);
-
-    Client* client = Client_Find(ev->window);
-    if (client)
-    {
-        if (ev->event == X.root)
-        {
-            Client_Del(client);
-        }
-        else if ( !(client->flags & F_SHADED) )
-        {
-            client->flags |= F_WITHDRAWN;
-            XUnmapWindow(X.disp, client->frame);
-        }
-    }
+    Event_Unmap(ev->window, ev->event);
 }
 
 /* Handle closed/destroyed windows */
@@ -60,12 +40,7 @@ static void xdestroynotify(XEvent* e)
 {
     XDestroyWindowEvent* ev = &(e->xdestroywindow);
     printf("DESTROY(w: 0x%lx)\n", ev->window);
-
-    Client* client = Client_Find(ev->window);
-    if (client)
-    {
-        Client_Del(client);
-    }
+    Event_Destroy(ev->window);
 }
 
 /* Handle window resize requests. Ignore them for tiled windows. */
@@ -81,65 +56,28 @@ static void xconfigrequest(XEvent* e)
     wc.border_width = ev->border_width;
     wc.sibling = ev->above;
     wc.stack_mode = ev->detail;
-
-    Client* client = Client_Find(ev->window);
-    if (client)
-    {
-        /* only allow floating clients to resize on their own */
-        if ((client->win == ev->window) && !client->column)
-        {
-            client->w = wc.width + FRAME_WIDTH_SUM;
-            client->h = wc.height + FRAME_HEIGHT_SUM;
-            Client_AdjustSize(client);
-            if (X.mode == M_RESIZE && Focused == client)
-            {
-                Mouse_ToCorner(client);
-            }
-        }
-    }
-    else
-    {
-        XConfigureWindow(X.disp, ev->window, ev->value_mask, &wc);
-    }
+    Event_Configure(ev->window, &wc, ev->value_mask);
 }
 
 /* Handle client messages. ICCM and EWMH stuff. */
 static void xclientmsg(XEvent* e)
 {
     XClientMessageEvent* ev = &(e->xclient);
-    printf("CLIENT_MSG(w: 0x%lx a: '%s')\n", ev->window, XGetAtomName(X.disp, ev->message_type));
-
-    if (ev->message_type == atom("_NET_ACTIVE_WINDOW"))
-    {
-        Client_SetActive(ev->window);
-    }
+    Event_Activate(ev->window);
 }
 
 /* Handle window properties */
 static void xpropnotify(XEvent* e)
 {
     XPropertyEvent* ev = &(e->xproperty);
-    printf("PROP_NOTIFY(w: 0x%lx)\n", ev->window);
-
-    Client* client = Client_Find(ev->window);
-    if (client)
-    {
-        Client_ReadProps(client);
-        Client_Draw(client);
-    }
+    Event_PropertyChange(ev->window);
 }
 
 /* Handle window focus. Focus follows mouse */
 static void xenternotify(XEvent* e)
 {
     XCrossingEvent* ev = &(e->xcrossing);
-    printf("ENTER(w: 0x%lx s: %d m: %d d: %d)\n", ev->window, ev->state, ev->mode, ev->detail);
-
-    Client* client = Client_Find(ev->window);
-    if (client)
-    {
-        Client_Focus(client);
-    }
+    Event_Enter(ev->window);
 }
 
 /* Handle redraw events */
@@ -148,12 +86,7 @@ static void xexpose(XEvent* e)
     XExposeEvent* ev = &(e->xexpose);
     if (ev->count == 0)
     {
-        printf("EXPOSE(w: 0x%lx)\n", ev->window);
-        Client* client = Client_Find(ev->window);
-        if (client)
-        {
-            Client_Draw(client);
-        }
+        Event_Redraw(ev->window);
     }
 }
 
@@ -163,72 +96,35 @@ static void xbtnpress(XEvent* e)
     XGrabPointer(X.disp, ev->window, False,
         ButtonPressMask | ButtonReleaseMask | ButtonMotionMask,
         GrabModeAsync, GrabModeAsync, None, X.csr_move, CurrentTime);
-    //printf("BTN_DN(w: 0x%lx s: %d x: %d y: %d rx: %d ry: %d)\n", ev->window, ev->state, ev->x, ev->y, ev->x_root, ev->y_root);
     X.start_x = ev->x_root, X.start_y = ev->y_root;
     X.last_x  = ev->x_root, X.last_y  = ev->y_root;
-
-
-    Client* client = Client_Find(ev->window);
-    if (client && (client->frame == ev->window))
-    {
-        if (ev->y < MIN_HEIGHT)
-        {
-            X.edge = E_TOP;
-        }
-        else if (ev->y_root > (client->y + client->h - BORDER_WIDTH))
-        {
-            X.edge = E_BOTTOM;
-        }
-        else if (ev->x < BORDER_WIDTH)
-        {
-            X.edge = E_LEFT;
-        }
-        else if (ev->x_root > (client->x + client->w - BORDER_WIDTH))
-        {
-            X.edge = E_RIGHT;
-        }
-        else
-        {
-            X.edge = E_NONE;
-        }
-        Mouse_Down(ev, client);
-    }
+    Event_ButtonPress(
+        ev->window,
+        ev->x,
+        ev->y,
+        ev->x_root,
+        ev->y_root
+    );
 }
 
 static void xbtnrelease(XEvent* e)
 {
     XButtonEvent* ev = &(e->xbutton);
-//    printf("BTN_UP(w: 0x%lx x: %d y: %d rx: %d ry: %d)\n", ev->window, ev->x, ev->y, ev->x_root, ev->y_root);
-
-    Client* client = Client_Find(ev->window);
-    if (client && (client->frame == ev->window))
-    {
-        Mouse_Up(ev, client);
-    }
-    X.mode = M_IDLE;
-    XUngrabPointer(X.disp, CurrentTime);
+    Event_ButtonRelease(ev->window);
 }
 
 static void xbtnmotion(XEvent* e)
 {
     /* make sure we get just the latest event */
     XMotionEvent *ev = &e->xmotion;
-//    printf("BTN_MV(w: 0x%lx x: %d y: %d rx: %d ry: %d)\n", ev->window, ev->x, ev->y, ev->x_root, ev->y_root);
-
     while (XCheckTypedWindowEvent(X.disp, ev->window, ev->type, e));
-    Client* client = Client_Find(ev->window);
-    if (client && (client->frame == ev->window))
-    {
-        Mouse_Drag(ev, client);
-    }
+    Event_ButtonMotion(ev->window);
     X.last_x = ev->x_root, X.last_y  = ev->y_root;
 }
 
 static void xkeypress(XEvent* e)
 {
     XKeyEvent* ev = &(e->xkey);
-    //printf("KEY_DN(w: 0x%lx)\n", ev->window);
-
     Keys_Run(ev);
 }
 
index 6ecb04eab71e39c2b6e7bc12db75258f85a5123d..73ec3662ed828224273fd1d4472eb747374fce19 100644 (file)
--- a/config.mk
+++ b/config.mk
@@ -3,7 +3,7 @@ OUTDIR = build
 BINDIR = $(OUTDIR)/bin
 
 CC = cc
-CFLAGS = -O2 --std=c11 -pedantic -Wall -Wextra -Werror -Wno-unused-result -Wno-sign-compare -Wno-type-limits -Wno-unused-parameter
+CFLAGS = -g -O2 --std=c11 -pedantic -Wall -Wextra -Werror -Wno-unused-result -Wno-sign-compare -Wno-type-limits -Wno-unused-parameter
 CPPFLAGS = -Iinc/ -I/usr/include/freetype2
 
 AR = ar
@@ -13,5 +13,6 @@ LDFLAGS = -flto -Lbuild/lib/ $(LIBS) -la
 LIBS =
 
 ARCHIVE = $(AR) $(ARFLAGS) $@ $^
-BINARY  = $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $^ $(LDFLAGS) && strip $@
+#BINARY  = $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $^ $(LDFLAGS) && strip $@
+BINARY  = $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $^ $(LDFLAGS)
 OBJECT  = $(CC) $(CFLAGS) $(CPPFLAGS) -MMD -c -o $@ $<
diff --git a/inc/fakes/X11.h b/inc/fakes/X11.h
new file mode 100644 (file)
index 0000000..e8a11fb
--- /dev/null
@@ -0,0 +1,686 @@
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+
+FAKE_VALUE_FUNC(Status, XInitImage, XImage*)
+
+//FAKE_VOID_FUNC(XrmInitialize, void)
+
+FAKE_VALUE_FUNC(Status, XGetAtomNames, Display*, Atom*, int, char**)
+
+FAKE_VALUE_FUNC(Atom, XInternAtom, Display*, _Xconst char*, Bool)
+
+FAKE_VALUE_FUNC(Status, XInternAtoms, Display*, char**, int, Bool, Atom*)
+
+FAKE_VALUE_FUNC(Colormap, XCopyColormapAndFree, Display*, Colormap)
+
+FAKE_VALUE_FUNC(Colormap, XCreateColormap, Display*, Window, Visual*, int)
+
+FAKE_VALUE_FUNC(Cursor, XCreatePixmapCursor, Display*, Pixmap, Pixmap, XColor*, XColor*, unsigned int, unsigned int)
+
+FAKE_VALUE_FUNC(Cursor, XCreateGlyphCursor, Display*, Font, Font, unsigned int, unsigned int, XColor _Xconst *, XColor _Xconst *)
+
+FAKE_VALUE_FUNC(Cursor, XCreateFontCursor, Display*, unsigned int)
+
+FAKE_VALUE_FUNC(Font, XLoadFont, Display*, _Xconst char*)
+
+FAKE_VALUE_FUNC(GC, XCreateGC, Display*, Drawable, unsigned long, XGCValues*)
+
+FAKE_VALUE_FUNC(GContext, XGContextFromGC, GC)
+
+FAKE_VOID_FUNC(XFlushGC, Display*, GC)
+
+FAKE_VALUE_FUNC(Pixmap, XCreatePixmap, Display*, Drawable, unsigned int, unsigned int, unsigned int)
+
+FAKE_VALUE_FUNC(Pixmap, XCreateBitmapFromData, Display*, Drawable, _Xconst char*, unsigned int, unsigned int)
+
+FAKE_VALUE_FUNC(Pixmap, XCreatePixmapFromBitmapData, Display*, Drawable, char*, unsigned int, unsigned int, unsigned long, unsigned long, unsigned int)
+
+FAKE_VALUE_FUNC(Window, XCreateSimpleWindow, Display*, Window, int, int, unsigned int, unsigned int, unsigned int, unsigned long, unsigned long)
+
+FAKE_VALUE_FUNC(Window, XGetSelectionOwner, Display*, Atom)
+
+FAKE_VALUE_FUNC(Window, XCreateWindow, Display*, Window, int, int, unsigned int, unsigned int, unsigned int, int, unsigned int, Visual*, unsigned long, XSetWindowAttributes*)
+
+FAKE_VALUE_FUNC(KeySym, XKeycodeToKeysym, Display*, KeyCode, int)
+
+FAKE_VALUE_FUNC(KeySym, XLookupKeysym, XKeyEvent*, int)
+
+FAKE_VALUE_FUNC(KeySym, XStringToKeysym, _Xconst char*)
+
+FAKE_VALUE_FUNC(long, XMaxRequestSize, Display*)
+
+FAKE_VALUE_FUNC(long, XExtendedMaxRequestSize, Display*)
+
+FAKE_VALUE_FUNC(VisualID, XVisualIDFromVisual, Visual*)
+
+//FAKE_VALUE_FUNC(Status, XInitThreads, void)
+
+FAKE_VOID_FUNC(XLockDisplay, Display*)
+
+FAKE_VOID_FUNC(XUnlockDisplay, Display*)
+
+FAKE_VALUE_FUNC(Window, XRootWindow, Display*, int)
+
+FAKE_VALUE_FUNC(Window, XDefaultRootWindow, Display*)
+
+FAKE_VALUE_FUNC(Window, XRootWindowOfScreen, Screen*)
+
+FAKE_VALUE_FUNC(GC, XDefaultGC, Display*, int)
+
+FAKE_VALUE_FUNC(GC, XDefaultGCOfScreen, Screen*)
+
+FAKE_VALUE_FUNC(Colormap, XDefaultColormap, Display*, int)
+
+FAKE_VALUE_FUNC(Colormap, XDefaultColormapOfScreen, Screen*)
+
+FAKE_VALUE_FUNC(long, XEventMaskOfScreen, Screen*)
+
+FAKE_VALUE_FUNC(int, XScreenNumberOfScreen, Screen*)
+
+FAKE_VALUE_FUNC(Status, XReconfigureWMWindow, Display*, Window, int, unsigned int, XWindowChanges*)
+
+FAKE_VALUE_FUNC(Status, XGetWMProtocols, Display*, Window, Atom**, int*)
+
+FAKE_VALUE_FUNC(Status, XSetWMProtocols, Display*, Window, Atom*, int)
+
+FAKE_VALUE_FUNC(Status, XIconifyWindow, Display*, Window, int)
+
+FAKE_VALUE_FUNC(Status, XWithdrawWindow, Display*, Window, int)
+
+FAKE_VALUE_FUNC(Status, XGetCommand, Display*, Window, char***, int*)
+
+FAKE_VALUE_FUNC(Status, XGetWMColormapWindows, Display*, Window, Window**, int*)
+
+FAKE_VALUE_FUNC(Status, XSetWMColormapWindows, Display*, Window, Window*, int)
+
+FAKE_VOID_FUNC(XFreeStringList, char**)
+
+FAKE_VALUE_FUNC(int, XSetTransientForHint, Display*, Window, Window)
+
+FAKE_VALUE_FUNC(int, XActivateScreenSaver, Display*)
+
+FAKE_VALUE_FUNC(int, XAddHost, Display*, XHostAddress*)
+
+FAKE_VALUE_FUNC(int, XAddHosts, Display*, XHostAddress*, int)
+
+FAKE_VALUE_FUNC(int, XAddToExtensionList, struct _XExtData**, XExtData*)
+
+FAKE_VALUE_FUNC(int, XAddToSaveSet, Display*, Window)
+
+FAKE_VALUE_FUNC(Status, XAllocColor, Display*, Colormap, XColor*)
+
+FAKE_VALUE_FUNC(Status, XAllocColorCells, Display*, Colormap, Bool        , unsigned long*, unsigned int, unsigned long*, unsigned int )
+
+FAKE_VALUE_FUNC(Status, XAllocColorPlanes, Display*, Colormap, Bool, unsigned long*, int, int, int, int, unsigned long*, unsigned long*, unsigned long*)
+
+FAKE_VALUE_FUNC(Status, XAllocNamedColor, Display*, Colormap, _Xconst char*, XColor*, XColor*)
+
+FAKE_VALUE_FUNC(int, XAllowEvents, Display*, int, Time)
+
+FAKE_VALUE_FUNC(int, XAutoRepeatOff, Display*)
+
+FAKE_VALUE_FUNC(int, XAutoRepeatOn, Display*)
+
+FAKE_VALUE_FUNC(int, XBell, Display*, int)
+
+FAKE_VALUE_FUNC(int, XBitmapBitOrder, Display*)
+
+FAKE_VALUE_FUNC(int, XBitmapPad, Display*)
+
+FAKE_VALUE_FUNC(int, XBitmapUnit, Display*)
+
+FAKE_VALUE_FUNC(int, XCellsOfScreen, Screen*)
+
+FAKE_VALUE_FUNC(int, XChangeActivePointerGrab, Display*, unsigned int, Cursor, Time)
+
+FAKE_VALUE_FUNC(int, XChangeGC, Display*, GC, unsigned long, XGCValues*)
+
+FAKE_VALUE_FUNC(int, XChangeKeyboardControl, Display*, unsigned long, XKeyboardControl*)
+
+FAKE_VALUE_FUNC(int, XChangeKeyboardMapping, Display*, int, int, KeySym*, int)
+
+FAKE_VALUE_FUNC(int, XChangePointerControl, Display*, Bool, Bool, int, int, int)
+
+FAKE_VALUE_FUNC(int, XChangeProperty, Display*, Window, Atom, Atom, int, int, _Xconst unsigned char*, int)
+
+FAKE_VALUE_FUNC(int, XChangeSaveSet, Display*, Window, int)
+
+FAKE_VALUE_FUNC(int, XChangeWindowAttributes, Display*, Window, unsigned long, XSetWindowAttributes* )
+
+//FAKE_VALUE_FUNC(Bool, XCheckIfEvent, Display*, XEvent*, Bool (*) (, Display*, XEvent*, XPointer, ), XPointer)
+
+FAKE_VALUE_FUNC(Bool, XCheckMaskEvent, Display*, long, XEvent*)
+
+FAKE_VALUE_FUNC(Bool, XCheckTypedEvent, Display*, int, XEvent*)
+
+FAKE_VALUE_FUNC(Bool, XCheckTypedWindowEvent, Display*, Window, int, XEvent*)
+
+FAKE_VALUE_FUNC(Bool, XCheckWindowEvent, Display*, Window, long, XEvent*)
+
+FAKE_VALUE_FUNC(int, XCirculateSubwindows, Display*, Window, int)
+
+FAKE_VALUE_FUNC(int, XCirculateSubwindowsDown, Display*, Window)
+
+FAKE_VALUE_FUNC(int, XCirculateSubwindowsUp, Display*, Window)
+
+FAKE_VALUE_FUNC(int, XClearArea, Display*, Window, int, int, unsigned int, unsigned int, Bool)
+
+FAKE_VALUE_FUNC(int, XClearWindow, Display*, Window)
+
+FAKE_VALUE_FUNC(int, XCloseDisplay, Display*)
+
+FAKE_VALUE_FUNC(int, XConfigureWindow, Display*, Window, unsigned int, XWindowChanges*)
+
+FAKE_VALUE_FUNC(int, XConnectionNumber, Display*)
+
+FAKE_VALUE_FUNC(int, XConvertSelection, Display*, Atom, Atom , Atom, Window, Time)
+
+FAKE_VALUE_FUNC(int, XCopyArea, Display*, Drawable, Drawable, GC, int, int, unsigned int, unsigned int, int, int)
+
+FAKE_VALUE_FUNC(int, XCopyGC, Display*, GC, unsigned long, GC)
+
+FAKE_VALUE_FUNC(int, XCopyPlane, Display*, Drawable, Drawable, GC, int, int, unsigned int, unsigned int, int, int, unsigned long)
+
+FAKE_VALUE_FUNC(int, XDefaultDepth, Display*, int)
+
+FAKE_VALUE_FUNC(int, XDefaultDepthOfScreen, Screen*)
+
+FAKE_VALUE_FUNC(int, XDefaultScreen, Display*)
+
+FAKE_VALUE_FUNC(int, XDefineCursor, Display*, Window, Cursor)
+
+FAKE_VALUE_FUNC(int, XDeleteProperty, Display*, Window, Atom)
+
+FAKE_VALUE_FUNC(int, XDestroyWindow, Display*, Window)
+
+FAKE_VALUE_FUNC(int, XDestroySubwindows, Display*, Window)
+
+FAKE_VALUE_FUNC(int, XDoesBackingStore, Screen*)
+
+FAKE_VALUE_FUNC(Bool, XDoesSaveUnders, Screen*)
+
+FAKE_VALUE_FUNC(int, XDisableAccessControl, Display*)
+
+FAKE_VALUE_FUNC(int, XDisplayCells, Display*, int)
+
+FAKE_VALUE_FUNC(int, XDisplayHeight, Display*, int)
+
+FAKE_VALUE_FUNC(int, XDisplayHeightMM, Display*, int)
+
+FAKE_VALUE_FUNC(int, XDisplayKeycodes, Display*, int*, int*)
+
+FAKE_VALUE_FUNC(int, XDisplayPlanes, Display*, int)
+
+FAKE_VALUE_FUNC(int, XDisplayWidth, Display*, int)
+
+FAKE_VALUE_FUNC(int, XDisplayWidthMM, Display*, int)
+
+FAKE_VALUE_FUNC(int, XDrawArc, Display*, Drawable, GC, int, int, unsigned int, unsigned int, int, int)
+
+FAKE_VALUE_FUNC(int, XDrawArcs, Display*, Drawable, GC, XArc*, int)
+
+FAKE_VALUE_FUNC(int, XDrawImageString, Display*, Drawable, GC, int, int, _Xconst char*, int)
+
+FAKE_VALUE_FUNC(int, XDrawImageString16, Display*, Drawable, GC, int, int, _Xconst XChar2b*, int)
+
+FAKE_VALUE_FUNC(int, XDrawLine, Display*, Drawable, GC, int, int, int, int)
+
+FAKE_VALUE_FUNC(int, XDrawLines, Display*, Drawable, GC, XPoint*, int, int)
+
+FAKE_VALUE_FUNC(int, XDrawPoint, Display*, Drawable, GC, int, int)
+
+FAKE_VALUE_FUNC(int, XDrawPoints, Display*, Drawable, GC, XPoint*, int, int)
+
+FAKE_VALUE_FUNC(int, XDrawRectangle, Display*, Drawable, GC, int, int, unsigned int, unsigned int)
+
+FAKE_VALUE_FUNC(int, XDrawRectangles, Display*, Drawable, GC, XRectangle*, int)
+
+FAKE_VALUE_FUNC(int, XDrawSegments, Display*, Drawable, GC, XSegment*, int)
+
+FAKE_VALUE_FUNC(int, XDrawString, Display*, Drawable, GC, int, int, _Xconst char*, int)
+
+FAKE_VALUE_FUNC(int, XDrawString16, Display*, Drawable, GC, int, int, _Xconst XChar2b*, int)
+
+FAKE_VALUE_FUNC(int, XDrawText, Display*, Drawable, GC, int, int, XTextItem*, int)
+
+FAKE_VALUE_FUNC(int, XDrawText16, Display*, Drawable, GC, int, int, XTextItem16*, int)
+
+FAKE_VALUE_FUNC(int, XEnableAccessControl, Display*)
+
+FAKE_VALUE_FUNC(int, XEventsQueued, Display*, int)
+
+FAKE_VALUE_FUNC(Status, XFetchName, Display*, Window, char**)
+
+FAKE_VALUE_FUNC(int, XFillArc, Display*, Drawable, GC, int, int, unsigned int, unsigned int, int, int)
+
+FAKE_VALUE_FUNC(int, XFillArcs, Display*, Drawable, GC, XArc*, int)
+
+FAKE_VALUE_FUNC(int, XFillPolygon, Display*, Drawable, GC, XPoint*, int, int, int)
+
+FAKE_VALUE_FUNC(int, XFillRectangle, Display*, Drawable, GC, int, int, unsigned int, unsigned int)
+
+FAKE_VALUE_FUNC(int, XFillRectangles, Display*, Drawable, GC, XRectangle*, int)
+
+FAKE_VALUE_FUNC(int, XFlush, Display*)
+
+FAKE_VALUE_FUNC(int, XForceScreenSaver, Display*, int)
+
+FAKE_VALUE_FUNC(int, XFree, void*)
+
+FAKE_VALUE_FUNC(int, XFreeColormap, Display*, Colormap)
+
+FAKE_VALUE_FUNC(int, XFreeColors, Display*, Colormap, unsigned long*, int, unsigned long)
+
+FAKE_VALUE_FUNC(int, XFreeCursor, Display*, Cursor)
+
+FAKE_VALUE_FUNC(int, XFreeExtensionList, char**)
+
+FAKE_VALUE_FUNC(int, XFreeFont, Display*, XFontStruct*)
+
+FAKE_VALUE_FUNC(int, XFreeFontInfo, char**, XFontStruct*, int)
+
+FAKE_VALUE_FUNC(int, XFreeFontNames, char**)
+
+FAKE_VALUE_FUNC(int, XFreeFontPath, char**)
+
+FAKE_VALUE_FUNC(int, XFreeGC, Display*, GC)
+
+FAKE_VALUE_FUNC(int, XFreeModifiermap, XModifierKeymap*)
+
+FAKE_VALUE_FUNC(int, XFreePixmap, Display*, Pixmap)
+
+FAKE_VALUE_FUNC(int, XGeometry, Display*, int, _Xconst char*, _Xconst char*, unsigned int, unsigned int, unsigned int, int, int, int*, int*, int*, int*)
+
+FAKE_VALUE_FUNC(int, XGetErrorDatabaseText, Display*, _Xconst char*, _Xconst char*, _Xconst char*, char*, int)
+
+FAKE_VALUE_FUNC(int, XGetErrorText, Display*, int, char*, int)
+
+FAKE_VALUE_FUNC(Bool, XGetFontProperty, XFontStruct*, Atom, unsigned long*)
+
+FAKE_VALUE_FUNC(Status, XGetGCValues, Display*, GC, unsigned long, XGCValues*)
+
+FAKE_VALUE_FUNC(Status, XGetGeometry, Display*, Drawable, Window*, int*, int*, unsigned int*, unsigned int*, unsigned int*, unsigned int*)
+
+FAKE_VALUE_FUNC(Status, XGetIconName, Display*, Window, char**)
+
+FAKE_VALUE_FUNC(int, XGetInputFocus, Display*, Window*, int*)
+
+FAKE_VALUE_FUNC(int, XGetKeyboardControl, Display*, XKeyboardState*)
+
+FAKE_VALUE_FUNC(int, XGetPointerControl, Display*, int*, int*, int*)
+
+FAKE_VALUE_FUNC(int, XGetPointerMapping, Display*, unsigned char*, int)
+
+FAKE_VALUE_FUNC(int, XGetScreenSaver, Display*, int*, int*, int*, int*)
+
+FAKE_VALUE_FUNC(Status, XGetTransientForHint, Display*, Window, Window*)
+
+FAKE_VALUE_FUNC(int, XGetWindowProperty, Display*, Window, Atom, long, long, Bool, Atom, Atom*, int*, unsigned long*, unsigned long*, unsigned char**)
+
+FAKE_VALUE_FUNC(Status, XGetWindowAttributes, Display*, Window, XWindowAttributes*)
+
+FAKE_VALUE_FUNC(int, XGrabButton, Display*, unsigned int, unsigned int, Window, Bool, unsigned int, int, int, Window, Cursor)
+
+FAKE_VALUE_FUNC(int, XGrabKey, Display*, int, unsigned int, Window, Bool, int, int)
+
+FAKE_VALUE_FUNC(int, XGrabKeyboard, Display*, Window, Bool, int, int, Time)
+
+FAKE_VALUE_FUNC(int, XGrabPointer, Display*, Window, Bool, unsigned int, int, int, Window, Cursor, Time)
+
+FAKE_VALUE_FUNC(int, XGrabServer, Display*)
+
+FAKE_VALUE_FUNC(int, XHeightMMOfScreen, Screen*)
+
+FAKE_VALUE_FUNC(int, XHeightOfScreen, Screen*)
+
+//FAKE_VALUE_FUNC(int, XIfEvent, Display*, XEvent*, Bool (*) (, Display*, XEvent*, XPointer, ), XPointer)
+
+FAKE_VALUE_FUNC(int, XImageByteOrder, Display*)
+
+FAKE_VALUE_FUNC(int, XInstallColormap, Display*, Colormap)
+
+FAKE_VALUE_FUNC(KeyCode, XKeysymToKeycode, Display*, KeySym)
+
+FAKE_VALUE_FUNC(int, XKillClient, Display*, XID)
+
+FAKE_VALUE_FUNC(Status, XLookupColor, Display*, Colormap, _Xconst char*, XColor*, XColor*)
+
+FAKE_VALUE_FUNC(int, XLowerWindow, Display*, Window)
+
+FAKE_VALUE_FUNC(int, XMapRaised, Display*, Window)
+
+FAKE_VALUE_FUNC(int, XMapSubwindows, Display*, Window)
+
+FAKE_VALUE_FUNC(int, XMapWindow, Display*, Window)
+
+FAKE_VALUE_FUNC(int, XMaskEvent, Display*, long, XEvent*)
+
+FAKE_VALUE_FUNC(int, XMaxCmapsOfScreen, Screen*)
+
+FAKE_VALUE_FUNC(int, XMinCmapsOfScreen, Screen*)
+
+FAKE_VALUE_FUNC(int, XMoveResizeWindow, Display*, Window, int, int, unsigned int, unsigned int)
+
+FAKE_VALUE_FUNC(int, XMoveWindow, Display*, Window, int, int)
+
+FAKE_VALUE_FUNC(int, XNextEvent, Display*, XEvent*)
+
+FAKE_VALUE_FUNC(int, XNoOp, Display*)
+
+FAKE_VALUE_FUNC(Status, XParseColor, Display*, Colormap, _Xconst char*, XColor*)
+
+FAKE_VALUE_FUNC(int, XParseGeometry, _Xconst char*, int*, int*, unsigned int*, unsigned int*)
+
+FAKE_VALUE_FUNC(int, XPeekEvent, Display*, XEvent*)
+
+//FAKE_VALUE_FUNC(int, XPeekIfEvent, Display*, XEvent*, Bool (*) (, Display*, XEvent*, XPointer, ), XPointer)
+
+FAKE_VALUE_FUNC(int, XPending, Display*)
+
+FAKE_VALUE_FUNC(int, XPlanesOfScreen, Screen*)
+
+FAKE_VALUE_FUNC(int, XProtocolRevision, Display*)
+
+FAKE_VALUE_FUNC(int, XProtocolVersion, Display*)
+
+FAKE_VALUE_FUNC(int, XPutBackEvent, Display*, XEvent*)
+
+FAKE_VALUE_FUNC(int, XPutImage, Display*, Drawable, GC, XImage*, int, int, int, int, unsigned int, unsigned int)
+
+FAKE_VALUE_FUNC(int, XQLength, Display*)
+
+FAKE_VALUE_FUNC(Status, XQueryBestCursor, Display*, Drawable, unsigned int        , unsigned int, unsigned int*, unsigned int*)
+
+FAKE_VALUE_FUNC(Status, XQueryBestSize, Display*, int, Drawable, unsigned int, unsigned int, unsigned int*, unsigned int*)
+
+FAKE_VALUE_FUNC(Status, XQueryBestStipple, Display*, Drawable, unsigned int, unsigned int, unsigned int*, unsigned int*)
+
+FAKE_VALUE_FUNC(Status, XQueryBestTile, Display*, Drawable, unsigned int, unsigned int, unsigned int*, unsigned int*)
+
+FAKE_VALUE_FUNC(int, XQueryColor, Display*, Colormap, XColor*)
+
+FAKE_VALUE_FUNC(int, XQueryColors, Display*, Colormap, XColor*, int)
+
+FAKE_VALUE_FUNC(Bool, XQueryExtension, Display*, _Xconst char*, int*, int*, int*)
+
+//FAKE_VALUE_FUNC(int, XQueryKeymap, Display*, char [32])
+
+FAKE_VALUE_FUNC(Bool, XQueryPointer, Display*, Window, Window*, Window*, int*, int*, int*, int*, unsigned int*       )
+
+FAKE_VALUE_FUNC(int, XQueryTextExtents, Display*, XID, _Xconst char*, int, int*, int*, int*, XCharStruct*)
+
+FAKE_VALUE_FUNC(int, XQueryTextExtents16, Display*, XID, _Xconst XChar2b*, int, int*, int*, int*, XCharStruct*)
+
+FAKE_VALUE_FUNC(Status, XQueryTree, Display*, Window, Window*, Window*, Window**, unsigned int*)
+
+FAKE_VALUE_FUNC(int, XRaiseWindow, Display*, Window)
+
+FAKE_VALUE_FUNC(int, XReadBitmapFile, Display*, Drawable , _Xconst char*, unsigned int*, unsigned int*, Pixmap*, int*, int*)
+
+FAKE_VALUE_FUNC(int, XReadBitmapFileData, _Xconst char*, unsigned int*, unsigned int*, unsigned char**, int*, int*)
+
+FAKE_VALUE_FUNC(int, XRebindKeysym, Display*, KeySym, KeySym*, int, _Xconst unsigned char*, int)
+
+FAKE_VALUE_FUNC(int, XRecolorCursor, Display*, Cursor, XColor*, XColor*)
+
+FAKE_VALUE_FUNC(int, XRefreshKeyboardMapping, XMappingEvent*)
+
+FAKE_VALUE_FUNC(int, XRemoveFromSaveSet, Display*, Window)
+
+FAKE_VALUE_FUNC(int, XRemoveHost, Display*, XHostAddress*)
+
+FAKE_VALUE_FUNC(int, XRemoveHosts, Display*, XHostAddress*, int)
+
+FAKE_VALUE_FUNC(int, XReparentWindow, Display*, Window, Window, int, int)
+
+FAKE_VALUE_FUNC(int, XResetScreenSaver, Display*)
+
+FAKE_VALUE_FUNC(int, XResizeWindow, Display*, Window, unsigned int, unsigned int)
+
+FAKE_VALUE_FUNC(int, XRestackWindows, Display*, Window*, int)
+
+FAKE_VALUE_FUNC(int, XRotateBuffers, Display*, int)
+
+FAKE_VALUE_FUNC(int, XRotateWindowProperties, Display*, Window, Atom*, int, int)
+
+FAKE_VALUE_FUNC(int, XScreenCount, Display*)
+
+FAKE_VALUE_FUNC(int, XSelectInput, Display*, Window, long)
+
+FAKE_VALUE_FUNC(Status, XSendEvent, Display*, Window, Bool, long, XEvent*)
+
+FAKE_VALUE_FUNC(int, XSetAccessControl, Display*, int)
+
+FAKE_VALUE_FUNC(int, XSetArcMode, Display*, GC, int)
+
+FAKE_VALUE_FUNC(int, XSetBackground, Display*, GC, unsigned long)
+
+FAKE_VALUE_FUNC(int, XSetClipMask, Display*, GC, Pixmap)
+
+FAKE_VALUE_FUNC(int, XSetClipOrigin, Display*, GC, int, int)
+
+FAKE_VALUE_FUNC(int, XSetClipRectangles, Display*, GC, int, int, XRectangle*, int, int)
+
+FAKE_VALUE_FUNC(int, XSetCloseDownMode, Display*, int)
+
+FAKE_VALUE_FUNC(int, XSetCommand, Display*, Window, char**, int)
+
+FAKE_VALUE_FUNC(int, XSetDashes, Display*, GC, int, _Xconst char*, int)
+
+FAKE_VALUE_FUNC(int, XSetFillRule, Display*, GC, int)
+
+FAKE_VALUE_FUNC(int, XSetFillStyle, Display*, GC, int)
+
+FAKE_VALUE_FUNC(int, XSetFont, Display*, GC, Font)
+
+FAKE_VALUE_FUNC(int, XSetFontPath, Display*, char**, int)
+
+FAKE_VALUE_FUNC(int, XSetForeground, Display*, GC, unsigned long)
+
+FAKE_VALUE_FUNC(int, XSetFunction, Display*, GC, int)
+
+FAKE_VALUE_FUNC(int, XSetGraphicsExposures, Display*, GC, Bool)
+
+FAKE_VALUE_FUNC(int, XSetIconName, Display*, Window, _Xconst char*)
+
+FAKE_VALUE_FUNC(int, XSetInputFocus, Display*, Window, int, Time)
+
+FAKE_VALUE_FUNC(int, XSetLineAttributes, Display*, GC, unsigned int, int, int, int)
+
+FAKE_VALUE_FUNC(int, XSetModifierMapping, Display*, XModifierKeymap*)
+
+FAKE_VALUE_FUNC(int, XSetPlaneMask, Display*, GC, unsigned long)
+
+FAKE_VALUE_FUNC(int, XSetPointerMapping, Display*, _Xconst unsigned char*, int)
+
+FAKE_VALUE_FUNC(int, XSetScreenSaver, Display*, int, int, int, int)
+
+FAKE_VALUE_FUNC(int, XSetSelectionOwner, Display*, Atom        , Window, Time)
+
+FAKE_VALUE_FUNC(int, XSetState, Display*, GC, unsigned long , unsigned long, int, unsigned long)
+
+FAKE_VALUE_FUNC(int, XSetStipple, Display*, GC, Pixmap)
+
+FAKE_VALUE_FUNC(int, XSetSubwindowMode, Display*, GC, int)
+
+FAKE_VALUE_FUNC(int, XSetTSOrigin, Display*, GC, int, int)
+
+FAKE_VALUE_FUNC(int, XSetTile, Display*, GC, Pixmap)
+
+FAKE_VALUE_FUNC(int, XSetWindowBackground, Display*, Window, unsigned long)
+
+FAKE_VALUE_FUNC(int, XSetWindowBackgroundPixmap, Display*, Window, Pixmap)
+
+FAKE_VALUE_FUNC(int, XSetWindowBorder, Display*, Window, unsigned long)
+
+FAKE_VALUE_FUNC(int, XSetWindowBorderPixmap, Display*, Window, Pixmap)
+
+FAKE_VALUE_FUNC(int, XSetWindowBorderWidth, Display*, Window, unsigned int)
+
+FAKE_VALUE_FUNC(int, XSetWindowColormap, Display*, Window, Colormap)
+
+FAKE_VALUE_FUNC(int, XStoreBuffer, Display*, _Xconst char*, int, int)
+
+FAKE_VALUE_FUNC(int, XStoreBytes, Display*, _Xconst char*, int)
+
+FAKE_VALUE_FUNC(int, XStoreColor, Display*, Colormap, XColor*)
+
+FAKE_VALUE_FUNC(int, XStoreColors, Display*, Colormap, XColor*, int)
+
+FAKE_VALUE_FUNC(int, XStoreName, Display*, Window, _Xconst char*)
+
+FAKE_VALUE_FUNC(int, XStoreNamedColor, Display*, Colormap, _Xconst char*, unsigned long, int)
+
+FAKE_VALUE_FUNC(int, XSync, Display*, Bool)
+
+FAKE_VALUE_FUNC(int, XTextExtents, XFontStruct*, _Xconst char*, int, int*, int*, int*, XCharStruct*)
+
+FAKE_VALUE_FUNC(int, XTextExtents16, XFontStruct*, _Xconst XChar2b*, int, int*, int*, int*, XCharStruct*)
+
+FAKE_VALUE_FUNC(int, XTextWidth, XFontStruct*, _Xconst char*, int)
+
+FAKE_VALUE_FUNC(int, XTextWidth16, XFontStruct*, _Xconst XChar2b*, int)
+
+FAKE_VALUE_FUNC(Bool, XTranslateCoordinates, Display*, Window, Window, int, int, int*, int*, Window*)
+
+FAKE_VALUE_FUNC(int, XUndefineCursor, Display*, Window)
+
+FAKE_VALUE_FUNC(int, XUngrabButton, Display*, unsigned int, unsigned int, Window)
+
+FAKE_VALUE_FUNC(int, XUngrabKey, Display*, int, unsigned int, Window)
+
+FAKE_VALUE_FUNC(int, XUngrabKeyboard, Display*, Time)
+
+FAKE_VALUE_FUNC(int, XUngrabPointer, Display*, Time)
+
+FAKE_VALUE_FUNC(int, XUngrabServer, Display*)
+
+FAKE_VALUE_FUNC(int, XUninstallColormap, Display*, Colormap)
+
+FAKE_VALUE_FUNC(int, XUnloadFont, Display*, Font)
+
+FAKE_VALUE_FUNC(int, XUnmapSubwindows, Display*, Window)
+
+FAKE_VALUE_FUNC(int, XUnmapWindow, Display*, Window)
+
+FAKE_VALUE_FUNC(int, XVendorRelease, Display*)
+
+FAKE_VALUE_FUNC(int, XWarpPointer, Display*, Window, Window, int, int, unsigned int, unsigned int, int, int)
+
+FAKE_VALUE_FUNC(int, XWidthMMOfScreen, Screen*)
+
+FAKE_VALUE_FUNC(int, XWidthOfScreen, Screen*)
+
+FAKE_VALUE_FUNC(int, XWindowEvent, Display*, Window, long, XEvent*)
+
+FAKE_VALUE_FUNC(int, XWriteBitmapFile, Display*, _Xconst char*, Pixmap, unsigned int, unsigned int, int, int)
+
+FAKE_VALUE_FUNC(XOM, XOpenOM, Display*, struct _XrmHashBucketRec*, _Xconst char*, _Xconst char*)
+
+FAKE_VALUE_FUNC(Status, XCloseOM, XOM)
+
+//FAKE_VALUE_FUNC(XOC, XCreateOC, XOM, ..., ) _X_SENTINEL(0);, , extern void XDestroyOC(, XOC)
+
+FAKE_VALUE_FUNC(XOM, XOMOfOC, XOC)
+
+FAKE_VALUE_FUNC(XFontSet, XCreateFontSet, Display*, _Xconst char*, char***, int*, char**)
+
+FAKE_VOID_FUNC(XFreeFontSet, Display*, XFontSet)
+
+FAKE_VALUE_FUNC(int, XFontsOfFontSet, XFontSet, XFontStruct***, char***)
+
+FAKE_VALUE_FUNC(Bool, XContextDependentDrawing, XFontSet)
+
+FAKE_VALUE_FUNC(Bool, XDirectionalDependentDrawing, XFontSet)
+
+FAKE_VALUE_FUNC(Bool, XContextualDrawing, XFontSet)
+
+FAKE_VALUE_FUNC(int, XmbTextEscapement, XFontSet, _Xconst char*, int)
+
+FAKE_VALUE_FUNC(int, XwcTextEscapement, XFontSet, _Xconst wchar_t*, int)
+
+FAKE_VALUE_FUNC(int, Xutf8TextEscapement, XFontSet, _Xconst char*, int)
+
+FAKE_VALUE_FUNC(int, XmbTextExtents, XFontSet, _Xconst char*, int, XRectangle*, XRectangle*)
+
+FAKE_VALUE_FUNC(int, XwcTextExtents, XFontSet, _Xconst wchar_t*, int, XRectangle*, XRectangle*)
+
+FAKE_VALUE_FUNC(int, Xutf8TextExtents, XFontSet, _Xconst char*, int, XRectangle*, XRectangle*)
+
+FAKE_VALUE_FUNC(Status, XmbTextPerCharExtents, XFontSet, _Xconst char*, int, XRectangle*, XRectangle*, int, int*, XRectangle*, XRectangle*)
+
+FAKE_VALUE_FUNC(Status, XwcTextPerCharExtents, XFontSet, _Xconst wchar_t*, int, XRectangle*, XRectangle*, int, int*, XRectangle*, XRectangle*)
+
+FAKE_VALUE_FUNC(Status, Xutf8TextPerCharExtents, XFontSet, _Xconst char*, int, XRectangle*, XRectangle*, int, int*, XRectangle*, XRectangle*)
+
+FAKE_VOID_FUNC(XmbDrawText, Display*, Drawable, GC, int, int, XmbTextItem*, int)
+
+FAKE_VOID_FUNC(XwcDrawText, Display*, Drawable, GC, int, int, XwcTextItem*, int)
+
+FAKE_VOID_FUNC(Xutf8DrawText, Display*, Drawable, GC, int, int, XmbTextItem*, int)
+
+FAKE_VOID_FUNC(XmbDrawString, Display*, Drawable, XFontSet, GC, int, int, _Xconst char*, int)
+
+FAKE_VOID_FUNC(XwcDrawString, Display*, Drawable, XFontSet, GC, int, int, _Xconst wchar_t*, int)
+
+FAKE_VOID_FUNC(Xutf8DrawString, Display*, Drawable, XFontSet, GC, int, int, _Xconst char*, int)
+
+FAKE_VOID_FUNC(XmbDrawImageString, Display*, Drawable, XFontSet, GC, int, int, _Xconst char*, int)
+
+FAKE_VOID_FUNC(XwcDrawImageString, Display*, Drawable, XFontSet, GC, int, int, _Xconst wchar_t*, int)
+
+FAKE_VOID_FUNC(Xutf8DrawImageString, Display*, Drawable, XFontSet, GC, int, int, _Xconst char*, int)
+
+FAKE_VALUE_FUNC(XIM, XOpenIM, Display*, struct _XrmHashBucketRec*, char*, char*)
+
+FAKE_VALUE_FUNC(Status, XCloseIM, XIM )
+
+//FAKE_VALUE_FUNC(XIC, XCreateIC, XIM  ..., ) _X_SENTINEL(0);, , extern void XDestroyIC(, XIC )
+
+FAKE_VOID_FUNC(XSetICFocus, XIC )
+
+FAKE_VOID_FUNC(XUnsetICFocus, XIC )
+
+FAKE_VALUE_FUNC(XIM, XIMOfIC, XIC )
+
+FAKE_VALUE_FUNC(Bool, XFilterEvent, XEvent*, Window)
+
+FAKE_VALUE_FUNC(int, XmbLookupString, XIC, XKeyPressedEvent*, char*, int, KeySym*, Status*)
+
+FAKE_VALUE_FUNC(int, XwcLookupString, XIC, XKeyPressedEvent*, wchar_t*, int, KeySym*, Status*)
+
+FAKE_VALUE_FUNC(int, Xutf8LookupString, XIC, XKeyPressedEvent*, char*, int, KeySym*, Status*)
+
+//FAKE_VALUE_FUNC(XVaNestedList, XVaCreateNestedList, int  ..., ) _X_SENTINEL(0);, , , , extern Bool XRegisterIMInstantiateCallback(, Display*, struct _XrmHashBucketRec*, char*, char*, XIDProc, XPointer)
+
+FAKE_VALUE_FUNC(Bool, XUnregisterIMInstantiateCallback, Display*, struct _XrmHashBucketRec*, char*, char*, XIDProc, XPointer)
+
+FAKE_VALUE_FUNC(Status, XInternalConnectionNumbers, Display*, int**, int*)
+
+FAKE_VOID_FUNC(XProcessInternalConnection, Display*, int)
+
+FAKE_VALUE_FUNC(Status, XAddConnectionWatch, Display*, XConnectionWatchProc, XPointer)
+
+FAKE_VOID_FUNC(XRemoveConnectionWatch, Display*, XConnectionWatchProc, XPointer)
+
+FAKE_VOID_FUNC(XSetAuthorization, char *, int, char *, int)
+
+FAKE_VALUE_FUNC(int, _Xmbtowc, wchar_t *, char *, int)
+
+FAKE_VALUE_FUNC(int, _Xwctomb, char *, wchar_t)
+
+FAKE_VALUE_FUNC(Bool, XGetEventData, Display*, XGenericEventCookie*)
+
+FAKE_VOID_FUNC(XFreeEventData, Display*, XGenericEventCookie*)
+
+FAKE_VALUE_FUNC(KeySym, XkbKeycodeToKeysym, Display*, KeyCode, int, int)
+
+FAKE_VALUE_FUNC(Bool, XineramaIsActive, Display*)
+
+FAKE_VALUE_FUNC(XineramaScreenInfo *, XineramaQueryScreens, Display*, int*)
+
+FAKE_VALUE_FUNC(Status, XGetWMNormalHints, Display*, Window, XSizeHints*, long*)
+
+FAKE_VALUE_FUNC(XWMHints*, XGetWMHints, Display*, Window)
+
+#pragma GCC diagnostic pop
diff --git a/inc/fakes/fff.h b/inc/fakes/fff.h
new file mode 100644 (file)
index 0000000..cdb1c46
--- /dev/null
@@ -0,0 +1,6588 @@
+/*
+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
+#ifndef FFF_GCC_FUNCTION_ATTRIBUTES
+    #define FFF_GCC_FUNCTION_ATTRIBUTES
+#endif
+#ifndef CUSTOM_FFF_FUNCTION_TEMPLATE
+#define CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN, FUNCNAME, ...) \
+    RETURN(*FUNCNAME)(__VA_ARGS__)
+#endif /* CUSTOM_FFF_FUNCTION_TEMPLATE */
+/* -- 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((void*)&FUNCNAME##_fake, 0, sizeof(FUNCNAME##_fake) - sizeof(FUNCNAME##_fake.custom_fake) - sizeof(FUNCNAME##_fake.custom_fake_seq)); \
+        FUNCNAME##_fake.custom_fake = NULL; \
+        FUNCNAME##_fake.custom_fake_seq = NULL; \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, void); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, void); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(void); \
+
+#define DEFINE_FAKE_VOID_FUNC0(FUNCNAME) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 != NULL){  \
+            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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0); \
+
+#define DEFINE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 != NULL){  \
+            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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1); \
+
+#define DEFINE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 != NULL){  \
+            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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 != NULL){  \
+            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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 != NULL){  \
+            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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 != NULL){  \
+            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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 != NULL){  \
+            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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 != NULL){  \
+            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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 != NULL){  \
+            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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 != NULL){  \
+            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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 != NULL){  \
+            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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 != NULL){  \
+            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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, 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; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 != NULL){  \
+            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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, 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); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, 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; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 != NULL){  \
+            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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, 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); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, 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; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 != NULL){  \
+            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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, 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); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, 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; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 != NULL){  \
+            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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, 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); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, 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; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 != NULL){  \
+            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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, 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); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, 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; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 != NULL){  \
+            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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, 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); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, 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; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 != NULL){  \
+            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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, 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); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, 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; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 != NULL){  \
+            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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, 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); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, 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; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 != NULL){  \
+            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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, void); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, void); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(void); \
+
+#define DEFINE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake != NULL){  \
+            RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0); \
+
+#define DEFINE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake != NULL){  \
+            RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake != NULL){  \
+            RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake != NULL){  \
+            RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake != NULL){  \
+            RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake != NULL){  \
+            RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake != NULL){  \
+            RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake != NULL){  \
+            RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake != NULL){  \
+            RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake != NULL){  \
+            RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake != NULL){  \
+            RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake != NULL){  \
+            RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, 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; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake != NULL){  \
+            RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, 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); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, 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; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake != NULL){  \
+            RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, 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); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, 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; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake != NULL){  \
+            RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, 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); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, 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; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake != NULL){  \
+            RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, 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); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, 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; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake != NULL){  \
+            RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \
+            SAVE_RET_HISTORY(FUNCNAME, ret); \
+            return ret; \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, 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); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, 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; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake != NULL){  \
+            RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(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_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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, 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); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, 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; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake != NULL){  \
+            RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(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_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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, 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); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, 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; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake != NULL){  \
+            RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(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_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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, 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); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, 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; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        if (FUNCNAME##_fake.custom_fake != NULL){  \
+            RETURN_TYPE ret = FUNCNAME##_fake.custom_fake(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_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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ...); \
+
+#define DEFINE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...); \
+
+#define DEFINE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, 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, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, 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, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, 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, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, 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, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, 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, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, 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, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, 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, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, 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, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, 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, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, 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, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, 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, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, 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, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, custom_fake, 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, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(void, *custom_fake_seq, 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, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    void FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES FUNCNAME(ARG0_TYPE arg0, ...); \
+
+#define DEFINE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \
+    FUNCNAME##_Fake FUNCNAME##_fake; \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, 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, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, 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, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, 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, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, 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, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, 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, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, 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, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, 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, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, 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, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, 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, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, 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, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, 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, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, 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, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        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 \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, custom_fake, 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, va_list ap); \
+        CUSTOM_FFF_FUNCTION_TEMPLATE(RETURN_TYPE, *custom_fake_seq, 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, va_list ap); \
+    } FUNCNAME##_Fake; \
+    extern FUNCNAME##_Fake FUNCNAME##_fake; \
+    void FUNCNAME##_reset(void); \
+    RETURN_TYPE FFF_GCC_FUNCTION_ATTRIBUTES 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 FFF_GCC_FUNCTION_ATTRIBUTES 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; \
+            } \
+        } \
+        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/test/winmgr/main.c b/test/winmgr/main.c
new file mode 100644 (file)
index 0000000..9ba1fc1
--- /dev/null
@@ -0,0 +1,57 @@
+#include "../../bin/winmgr/anvil.h"
+
+#include "fakes/fff.h"
+DEFINE_FFF_GLOBALS
+#include "fakes/X11.h"
+
+#define INCLUDE_DEFS
+#include "atf.h"
+
+XFontSetExtents font_ext;
+XConf X;
+
+extern unsigned long Client_Bitmap[NUM_BITMAP_CELLS];
+extern Client Client_Buffer[MAX_CLIENTS];
+extern Client* Focused;
+
+void initialize(void)
+{
+    X.font_ext = &font_ext;
+    font_ext.max_logical_extent.height = 10;
+    memset(Client_Bitmap, 0, sizeof(Client_Bitmap));
+    memset(Client_Buffer, 0, sizeof(Client_Buffer));
+    Focused = NULL;
+}
+
+int main(int argc, char** argv)
+{
+    atf_init(argc, argv);
+    initialize();
+    RUN_EXTERN_TEST_SUITE(Events);
+    return atf_print_results();
+}
+
+TEST_SUITE(Events)
+{
+    TEST(Mapping two windows)
+    {
+        initialize();
+        XWindowAttributes attr = {0};
+        Event_Map(42, &attr);
+        CHECK(Client_Bitmap[0] == 1);
+    }
+
+    TEST(Unmapping the two windows)
+    {
+        initialize();
+        XWindowAttributes attr = {0};
+        Event_Map(42, &attr);
+        CHECK(Client_Bitmap[0] == 1);
+        Event_Map(24, &attr);
+        CHECK(Client_Bitmap[0] == 3);
+        Event_Unmap(24, 1);
+        CHECK(Client_Bitmap[0] == 1);
+        Event_Unmap(42, 1);
+        CHECK(Client_Bitmap[0] == 0);
+    }
+}
\ No newline at end of file