LibComponentLogging-Core icon indicating copy to clipboard operation
LibComponentLogging-Core copied to clipboard

Swift support

Open stefanfisk opened this issue 10 years ago • 6 comments

I know this is a large and open question for a macro based library like LCL, but are there any thoughts about adding Swift support?

Right now I'm working on a mixed project, and the fact that my logging is a world of pain compared to the wonderful qlog makes me sad 😿

I'd be willing to do some coding if anyone can come up with a nice approach, and and all constructive suggestions would be much appreciated!

stefanfisk avatar Apr 09 '15 09:04 stefanfisk

No nice ideas from my side yet :(

aharren avatar Apr 16 '15 20:04 aharren

So I just had an epiphany:

lcl.swift

class lcl {
    private let _component: _lcl_enum_component_t;

    init(_ component: _lcl_enum_component_t) {
        _component = component
    }

    private func log(level: _lcl_enum_level_t, @autoclosure message: () -> String) {
        let activeLevel = _lcl_component_level_ptr[Int(level.rawValue)]

        if level.rawValue < UInt32(activeLevel) {
            return
        }

        _lcl_logger_swift_support(_component.rawValue, level.rawValue, message())
    }

    func critical(@autoclosure message: () -> String = "") {
        log(lcl_vCritical, message: message)
    }
    func error(@autoclosure message: () -> String = "") {
        log(lcl_vError, message: message)
    }
    func warning(@autoclosure message: () -> String = "") {
        log(lcl_vWarning, message: message)
    }
    func info(@autoclosure message: () -> String = "") {
        log(lcl_vInfo, message: message)
    }
    func debug(@autoclosure message: () -> String = "") {
        log(lcl_vDebug, message: message)
    }
    func trace(@autoclosure message: () -> String = "") {
        log(lcl_vTrace, message: message)
    }
}

lcl_swift.h

#import <lcl.h>

extern _lcl_level_narrow_t* _lcl_component_level_ptr;

static inline void _lcl_logger_swift_support(_lcl_component_t component, _lcl_level_t level, const char* message) {
    _lcl_logger(component, level, "%s", message);
}

lcl_swift.h

#import "lcl_swift.h"

_lcl_level_narrow_t* _lcl_component_level_ptr = _lcl_component_level;

Then in the top of you source file do:

private let log = lcl(lcl_cComponent)

And you will be able to log via log.trace("Test") etc.

stefanfisk avatar Mar 20 '16 22:03 stefanfisk

The c wrangling can probably be cleaned up, but my understanding of Swift<->C interoperability is far from complete.

stefanfisk avatar Mar 20 '16 22:03 stefanfisk

Aaaand I just realized it is missing file/line/function/etc...

Will do another take tomorrow, and if it all feels good probably create a Pod.

stefanfisk avatar Mar 20 '16 22:03 stefanfisk

That sounds promising :)

aharren avatar Mar 21 '16 19:03 aharren

Alright, I've got it working, but I am not sure how to package it as a pod. The issue is that the following code needs to be built with _lcl_logger defined, and preferably with -w to suppress warnings related to redefining builtins. Do you have any idea on how to best achieve that?

#import "lcl_swift.h"

_lcl_level_narrow_t* _lcl_component_level_swift_support = _lcl_component_level;

void _lcl_logger_swift_support(_lcl_component_t component, _lcl_level_t level, const char* message, const char* file, long line, const char* function) {
    #define __FILE__ file
    #define __LINE__ (int)line
    #define __PRETTY_FUNCTION__ function
    #define __func__ function
    #define __FUNCTION__ function

    _lcl_logger(component, level, "%s", message);
}

stefanfisk avatar Mar 29 '16 13:03 stefanfisk