Set the signatures of most visa functions in the library.

    All instrumentation related functions are specified here.

    :param library: the visa library wrapped by ctypes.
    :type library: ctypes.WinDLL or ctypes.CDLL
    :param errcheck: error checking callable used for visa functions that return
                     ViStatus.
                     It should be take three areguments (result, func, arguments).
                     See errcheck in ctypes.

def set_signatures(library, errcheck=None):
    """Set the signatures of most visa functions in the library.

    All instrumentation related functions are specified here.

    :param library: the visa library wrapped by ctypes.
    :type library: ctypes.WinDLL or ctypes.CDLL
    :param errcheck: error checking callable used for visa functions that return
                     ViStatus.
                     It should be take three areguments (result, func, arguments).
                     See errcheck in ctypes.
    """

    # Somehow hasattr(library, '_functions') segfaults in cygwin (See #131)
    if '_functions' not in dir(library):
        library._functions = []
        library._functions_failed = []

    def _applier(restype, errcheck_):
        def _internal(function_name, argtypes, required=False):
            try:
                set_signature(library, function_name, argtypes, restype, errcheck_)
                # noinspection PyProtectedMember
                library._functions.append(function_name)
            except AttributeError:
                library._functions_failed.append(function_name)
                if required:
                    raise
        return _internal

    # Visa functions with ViStatus return code
    apply = _applier(ViStatus, errcheck)
    apply("viAssertIntrSignal", [ViSession, ViInt16, ViUInt32])
    apply("viAssertTrigger", [ViSession, ViUInt16])
    apply("viAssertUtilSignal", [ViSession, ViUInt16])
    apply("viBufRead", [ViSession, ViPBuf, ViUInt32, ViPUInt32])
    apply("viBufWrite", [ViSession, ViBuf, ViUInt32, ViPUInt32])
    apply("viClear", [ViSession])
    apply("viClose", [ViObject])
    apply("viDisableEvent", [ViSession, ViEventType, ViUInt16])
    apply("viDiscardEvents", [ViSession, ViEventType, ViUInt16])
    apply("viEnableEvent", [ViSession, ViEventType, ViUInt16, ViEventFilter])
    apply("viFindNext", [ViSession, ViAChar])
    apply("viFindRsrc", [ViSession, ViString, ViPFindList, ViPUInt32, ViAChar])
    apply("viFlush", [ViSession, ViUInt16])
    apply("viGetAttribute", [ViObject, ViAttr, c_void_p])
    apply("viGpibCommand", [ViSession, ViBuf, ViUInt32, ViPUInt32])
    apply("viGpibControlATN", [ViSession, ViUInt16])
    apply("viGpibControlREN", [ViSession, ViUInt16])
    apply("viGpibPassControl", [ViSession, ViUInt16, ViUInt16])
    apply("viGpibSendIFC", [ViSession])

    apply("viIn8", [ViSession, ViUInt16, ViBusAddress, ViPUInt8])
    apply("viIn16", [ViSession, ViUInt16, ViBusAddress, ViPUInt16])
    apply("viIn32", [ViSession, ViUInt16, ViBusAddress, ViPUInt32])
    apply("viIn64", [ViSession, ViUInt16, ViBusAddress, ViPUInt64])

    apply("viIn8Ex", [ViSession, ViUInt16, ViBusAddress64, ViPUInt8])
    apply("viIn16Ex", [ViSession, ViUInt16, ViBusAddress64, ViPUInt16])
    apply("viIn32Ex", [ViSession, ViUInt16, ViBusAddress64, ViPUInt32])
    apply("viIn64Ex", [ViSession, ViUInt16, ViBusAddress64, ViPUInt64])

    apply("viInstallHandler", [ViSession, ViEventType, ViHndlr, ViAddr])
    apply("viLock", [ViSession, ViAccessMode, ViUInt32, ViKeyId, ViAChar])
    apply("viMapAddress", [ViSession, ViUInt16, ViBusAddress, ViBusSize, ViBoolean, ViAddr, ViPAddr])
    apply("viMapTrigger", [ViSession, ViInt16, ViInt16, ViUInt16])
    apply("viMemAlloc", [ViSession, ViBusSize, ViPBusAddress])
    apply("viMemFree", [ViSession, ViBusAddress])
    apply("viMove", [ViSession, ViUInt16, ViBusAddress, ViUInt16,
                     ViUInt16, ViBusAddress, ViUInt16, ViBusSize])
    apply("viMoveAsync", [ViSession, ViUInt16, ViBusAddress, ViUInt16,
                          ViUInt16, ViBusAddress, ViUInt16, ViBusSize,
                          ViPJobId])

    apply("viMoveIn8", [ViSession, ViUInt16, ViBusAddress, ViBusSize, ViAUInt8])
    apply("viMoveIn16", [ViSession, ViUInt16, ViBusAddress, ViBusSize, ViAUInt16])
    apply("viMoveIn32", [ViSession, ViUInt16, ViBusAddress, ViBusSize, ViAUInt32])
    apply("viMoveIn64", [ViSession, ViUInt16, ViBusAddress, ViBusSize, ViAUInt64])

    apply("viMoveIn8Ex", [ViSession, ViUInt16, ViBusAddress64, ViBusSize, ViAUInt8])
    apply("viMoveIn16Ex", [ViSession, ViUInt16, ViBusAddress64, ViBusSize, ViAUInt16])
    apply("viMoveIn32Ex", [ViSession, ViUInt16, ViBusAddress64, ViBusSize, ViAUInt32])
    apply("viMoveIn64Ex", [ViSession, ViUInt16, ViBusAddress64, ViBusSize, ViAUInt64])

    apply("viMoveOut8", [ViSession, ViUInt16, ViBusAddress, ViBusSize, ViAUInt8])
    apply("viMoveOut16", [ViSession, ViUInt16, ViBusAddress, ViBusSize, ViAUInt16])
    apply("viMoveOut32", [ViSession, ViUInt16, ViBusAddress, ViBusSize, ViAUInt32])
    apply("viMoveOut64", [ViSession, ViUInt16, ViBusAddress, ViBusSize, ViAUInt64])

    apply("viMoveOut8Ex", [ViSession, ViUInt16, ViBusAddress64, ViBusSize, ViAUInt8])
    apply("viMoveOut16Ex", [ViSession, ViUInt16, ViBusAddress64, ViBusSize, ViAUInt16])
    apply("viMoveOut32Ex", [ViSession, ViUInt16, ViBusAddress64, ViBusSize, ViAUInt32])
    apply("viMoveOut64Ex", [ViSession, ViUInt16, ViBusAddress64, ViBusSize, ViAUInt64])

    apply("viOpen", [ViSession, ViRsrc, ViAccessMode, ViUInt32, ViPSession], required=True)

    apply("viOpenDefaultRM", [ViPSession], required=True)

    apply("viOut8", [ViSession, ViUInt16, ViBusAddress, ViUInt8])
    apply("viOut16", [ViSession, ViUInt16, ViBusAddress, ViUInt16])
    apply("viOut32", [ViSession, ViUInt16, ViBusAddress, ViUInt32])
    apply("viOut64", [ViSession, ViUInt16, ViBusAddress, ViUInt64])

    apply("viOut8Ex", [ViSession, ViUInt16, ViBusAddress64, ViUInt8])
    apply("viOut16Ex", [ViSession, ViUInt16, ViBusAddress64, ViUInt16])
    apply("viOut32Ex", [ViSession, ViUInt16, ViBusAddress64, ViUInt32])
    apply("viOut64Ex", [ViSession, ViUInt16, ViBusAddress64, ViUInt64])

    apply("viParseRsrc", [ViSession, ViRsrc, ViPUInt16, ViPUInt16])
    apply("viParseRsrcEx", [ViSession, ViRsrc, ViPUInt16, ViPUInt16, ViAChar, ViAChar, ViAChar])

    apply("viRead", [ViSession, ViPBuf, ViUInt32, ViPUInt32])
    apply("viReadAsync", [ViSession, ViPBuf, ViUInt32, ViPJobId])
    apply("viReadSTB", [ViSession, ViPUInt16])
    apply("viReadToFile", [ViSession, ViString, ViUInt32, ViPUInt32])

    apply("viSetAttribute", [ViObject, ViAttr, ViAttrState])
    apply("viSetBuf", [ViSession, ViUInt16, ViUInt32])

    apply("viStatusDesc", [ViObject, ViStatus, ViAChar])
    apply("viTerminate", [ViSession, ViUInt16, ViJobId])
    apply("viUninstallHandler", [ViSession, ViEventType, ViHndlr, ViAddr])
    apply("viUnlock", [ViSession])
    apply("viUnmapAddress", [ViSession])
    apply("viUnmapTrigger", [ViSession, ViInt16, ViInt16])
    apply("viUsbControlIn", [ViSession, ViInt16, ViInt16, ViUInt16,
                             ViUInt16, ViUInt16, ViPBuf, ViPUInt16])
    apply("viUsbControlOut", [ViSession, ViInt16, ViInt16, ViUInt16,
                              ViUInt16, ViUInt16, ViPBuf])

    # The following "V" routines are *not* implemented in PyVISA, and will
    # never be: viVPrintf, viVQueryf, viVScanf, viVSPrintf, viVSScanf

    apply("viVxiCommandQuery", [ViSession, ViUInt16, ViUInt32, ViPUInt32])
    apply("viWaitOnEvent", [ViSession, ViEventType, ViUInt32, ViPEventType, ViPEvent])
    apply("viWrite", [ViSession, ViBuf, ViUInt32, ViPUInt32])
    apply("viWriteAsync", [ViSession, ViBuf, ViUInt32, ViPJobId])
    apply("viWriteFromFile", [ViSession, ViString, ViUInt32, ViPUInt32])

    # Functions that return void.
    apply = _applier(None, None)
    apply("viPeek8", [ViSession, ViAddr, ViPUInt8])
    apply("viPeek16", [ViSession, ViAddr, ViPUInt16])
    apply("viPeek32", [ViSession, ViAddr, ViPUInt32])
    apply("viPeek64", [ViSession, ViAddr, ViPUInt64])

    apply("viPoke8", [ViSession, ViAddr, ViUInt8])
    apply("viPoke16", [ViSession, ViAddr, ViUInt16])
    apply("viPoke32", [ViSession, ViAddr, ViUInt32])
    apply("viPoke64", [ViSession, ViAddr, ViUInt64])