воскресенье, 26 августа 2018 г.

Псевдозамыкания на С

 #include <stdio.h>  
 #include <stdlib.h>  
 #include <stdarg.h>  

static int _dump(char *psDstBuf_      , size_t nSizeDstBuf_, 
                 const void *pSrcBuf_ , size_t nSizeSrcBuf_)  
{  
    const char aHexSymbol[] = { 
                                '0', '1', '2', '3', '4', '5', '6', '7',
                                '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' 
                              };  
    size_t iSrcBuf = 0;  
    size_t iDstBuf = 0;  
    unsigned char cByte = '\0';

    if ( nSizeDstBuf_ < 3 ) { return 0; }
  
    for (iSrcBuf=0; iSrcBuf<nSizeSrcBuf_; ++iSrcBuf) {
      if ( ( nSizeDestBuf_ - iSrcBuf * 3 ) < 3 ) { break; }
      cByte = ((const unsigned char*) pSrcBuf_)[iSrcBuf];
      psDstBuf_[iDstBuf++] = aHexSymbol[(cByte >> 4) & 0b1111];
      psDstBuf_[iDstBuf++] = aHexSymbol[cByte & 0b1111];
      psDstBuf_[iDstBuf++] = ( (iSrcBuf & 0b1111) == 0b1111) ? '\n' : ' ';
    }

    psDstBuf_[iDstBuf ? iDstBuf - 1 : 0] = '\0';

    return ( iSrcBuf * 3 );  
}

#define LOG(fBufFiller, nSizeData)                        \
({                                                        \  
    char *psDumpMessage = (char*) calloc(nSizeData, 1);   \  
                                                          \
    fBufFiller(psDumpMessage);                            \
                                                          \
    printf("%s", psDumpMessage);                          \
                                                          \
    free(psDumpMessage);                                  \
})
  
static void _message_error(const char *psFormat_, ...)  
{  
    va_list nArgs;

    va_start(nArgs, psFormat_);  
    size_t nSizeMsg = vsnprintf(NULL, 0, psFormat_, nArgs);  
    va_end(nArgs);  
    
    #define fBufFiller(psBuf)                \
    ({                                       \
        va_start(nArgs, psFormat_);          \
        vsprintf(psBuf, psFormat_, nArgs);   \
        va_end(nArgs);                       \
    })
  
    LOG(fBufFiller, nSizeMsg);
  
    #undef fBufFiller  
}

static void _message_dump(void *pDataDump_, unsigned int nSizeDump_)  
{  
    const size_t nSizeBuf = nSizeDump_ * 3;  
    
    #define fBufFiller(psBuf)                             \
    ({                                                    \
        _dump(psBuf, nSizeBuf, pDataDump_, nSizeDump_);   \  
    })

    LOG(fBufFiller, nSizeBuf);

    #undef fBufFiller  
}

static void _message_state_report(int iModule_, int nError_)  
{  
    const size_t nSizeBuf = 64;
 
    #define fBufFiller(psBuf)                                              \
    ({                                                                     \
        const char *psState = nError_ ? "unworkable" : "workable";         \
        sprintf(psBuf, "Report for module #%d: %s ", iModule_, psState);   \  
    })

    LOG(fBufFiller, nSizeBuf);

    #undef fBufFiller  
}

int main(void)  
{  
    int aRandomData[] = { 9, 8, 7, 6, 5 };

    _message_error("Sending packet '%s' is failed (code error: %d)", "bpdu_tcn", 3);  
    printf("\n\n");  

    _message_state_report(3, 5);  
    printf("\n\n");  

    _message_dump(aRandomData, sizeof(aRandomData));  
    printf("\n\n");  
    
    return 0;
}

Комментариев нет:

Отправить комментарий