Browse Source

Initial commit

master
dirkson 5 years ago
commit
bd5c56515f
  1. 3
      .gitignore
  2. 9
      LICENSE
  3. 122
      Makefile
  4. 54
      README.md
  5. 6
      src/dependencies/README
  6. 5655
      src/dependencies/tinyfiledialogs.c
  7. 298
      src/dependencies/tinyfiledialogs.h
  8. 7
      src/examples/basic.c
  9. 18
      src/examples/test.c
  10. 215
      src/lob.c
  11. 68
      src/lob.h
  12. 46
      src/lobtions.h
  13. 4
      test

3
.gitignore

@ -0,0 +1,3 @@
*.un~
*.o
*.swp

9
LICENSE

@ -0,0 +1,9 @@
Copyright (c) 2016 Orangehattech, LLC
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.

122
Makefile

@ -0,0 +1,122 @@
# Makefile for lob tests
#
#
# -------
# -Tools-
# -------
#ccache, if available
ifeq ($(shell { which ccache; } 2>/dev/null), )
PRECC :=
else
PRECC := ccache
endif
#prefer clang, but use gcc if we need to
ifeq ($(shell { which clang; } 2>/dev/null), )
CC := gcc
else
CC := clang
endif
# -------
# -Files-
# -------
LOBSRC := $(wildcard src/*.c)
LOBOBJ := $(addprefix obj/,$(notdir $(LOBSRC:.c=.o)))
TSTSRC := $(wildcard src/examples/*.c)
TSTOBJ := $(addprefix obj/,$(notdir $(TSTSRC:.c=.o)))
TSTPLN := $(notdir $(TSTSRC:.c=))
TSTBIN := $(addprefix bin/,$(TSTPLN))
# ------
# -Opts-
# ------
#Do not allow warnings to compile
FLAGS = -Werror
#Enable some fancy optimizations, just in case those mess something up
FLAGS += -O3
#Make sure we can still debug
#FLAGS += -fno-inline -fno-omit-frame-pointer
#FLAGS += -g3 -ggdb
#Maybe in the future we'll use some of clang's sanitizers?
#FLAGS += -fsanitize=memory,undefined -fno-optimize-sibling-calls
COMPILE := $(PCC) $(CC) $(FLAGS) -I src/ -I src/dependencies
#test: FLAGS +=
# --------
# -Builds-
# --------
lob: | lobdirs
lob: lib/liblob.a
obj/%.o: src/dependencies/%.c
$(COMPILE) -c -o $@ $<
obj/%.o: src/%.c
$(COMPILE) -c -o $@ $<
lib/liblob.a: $(LOBOBJ) obj/tinyfiledialogs.o
$(PRECC) ar rcs $@ $< obj/tinyfiledialogs.o
obj/%.o: src/examples/%.c
$(COMPILE) -c -o $@ $<
bin/%: obj/%.o | exampledirs
$(COMPILE) -rdynamic -o $@ $^ lib/liblob.a
basic: lob bin/basic
test: lob bin/test
examples: basic test
#Make will delete these files unless we go all gollum-style on them.
.PRECIOUS: obj/%.o
# --------
# -mkdirs-
# --------
exampledirs:
@mkdir -p bin
lobdirs:
@mkdir -p obj
@mkdir -p lib
# -------
# -Clean-
# -------
lobclean:
@rm -f obj/lob.o
@rm -f lib/liblob.a
objclean:
@rm -f obj/*.o
binclean:
@rm -f bin/*
# --------------
# -Combinations-
# --------------
clean: | lobclean binclean objclean
all: | lob

54
README.md

@ -0,0 +1,54 @@
**Lob**
Lob (or liblob) is a cross-platform, MIT-licensed, thread-safe, statically-compiled logging library written in C89.
It will display errors, warnings, and other messages via stdout, stderr, gui boxes, or direct writes to files.
It's designed to be minimal and only include the code *you* need. It should compile on Linux, OSX, and windows.
It mostly exists because I noticed I kept copy/pasting a debug-output file to all my projects.
**Documentation**
To build, type 'make'. Output is lib/liblob.a , which should be usable in most C projects.
To build examples, type 'make examples'. Output is bin/test and bin/basic
The externally visible logging function is:
```
char lob(const unsigned char OutputFlags, const char Level, const char *Format, ...)
```
OutputFlags can be any mixture of the following, bitwise-or'd together:
```
LOB_STDOUT
LOB_FILE
LOB_GUIBOX
```
Level can be any of the following:
```
LOB_ERROR
LOB_WARN
LOB_INFO
LOB_DEBUG
```
Format is a printf-style formatted string. It is followed by a list of variables, in the printf style.
lob() returns whatever you passed it as "Level". By default, this will resolve to C's 'false' for LOB\_ERROR, and 'true' for all others
The following example will print out its message in stdout and to a gui box, then return 0 to the parent function:
```
if (SomeCondition == Failure)
return lob(LOB_STDOUT | LOB_GUIBOX, LOB_ERROR, "Oops! The following failure condition happened: %i", SomeCondition);
```
Additional options are available at compile time. See lobtions.h
**TODO**
Add loblvl() to allow users to change logging level at runtime.
Add some method to allow users to introduce their own callbacks.
Add some method of internet-capable logging.
Add logging to syslog.

6
src/dependencies/README

@ -0,0 +1,6 @@
tinyfiledialogs, by Guillaume Vareille, is used under a zlib licence
At the time of this writing, tinyfiledialogs is only available here:
https://sourceforge.net/projects/tinyfiledialogs/

5655
src/dependencies/tinyfiledialogs.c
File diff suppressed because it is too large
View File

298
src/dependencies/tinyfiledialogs.h

@ -0,0 +1,298 @@
/*
_________
/ \ tinyfiledialogs.h v2.7.2 [November 23, 2016] zlib licence
|tiny file| Unique header file of "tiny file dialogs" created [November 9, 2014]
| dialogs | Copyright (c) 2014 - 2016 Guillaume Vareille http://ysengrin.com
\____ ___/ http://tinyfiledialogs.sourceforge.net
\|
git://git.code.sf.net/p/tinyfiledialogs/code
_____________________________________________________
| |
| direct CONTACT: mailto:tinyfiledialogs@ysengrin.com |
|______________________________________________________|
A big thank you to Don Heyse http://ldglite.sf.net for
his code contributions, bug corrections & thorough testing!
git://git.code.sf.net/p/tinyfiledialogs/code
Please
1) let me know
- if you are including tiny file dialogs,
I'll be happy to add your link to the list of projects using it.
- If you are using it on different hardware / OS / compiler.
2) Be the first to leave a review on Sourceforge. Thanks.
tiny file dialogs (cross-platform C C++)
InputBox PasswordBox MessageBox ColorPicker
OpenFileDialog SaveFileDialog SelectFolderDialog
Native dialog library for WINDOWS MAC OSX GTK+ QT CONSOLE & more
A single C file (add it to your C or C++ project) with 6 boxes:
- message / question
- input / password
- save file
- open file & multiple files
- select folder
- color picker.
Complements OpenGL GLFW GLUT GLUI VTK SFML SDL Ogre Unity ION
CEGUI MathGL CPW GLOW IMGUI GLT NGL STB & GUI less programs
NO INIT
NO MAIN LOOP
The dialogs can be forced into console mode
Windows (XP to 10) [ASCII + MBCS + UTF-8 + UTF-16]
- native code & some vbs create the graphic dialogs
- enhanced console mode can use dialog.exe from
http://andrear.altervista.org/home/cdialog.php
- basic console input
Unix (command line call attempts) [ASCII + UTF-8]
- applescript
- zenity / matedialog
- kdialog
- Xdialog
- python2 tkinter
- dialog (opens a console if needed)
- basic console input
The same executable can run across desktops & distributions
tested with C & C++ compilers
on VisualStudio MinGW Mac Linux Bsd Solaris Minix Raspbian
using Gnome Kde Enlightenment Mate Cinnamon Unity
Lxde Lxqt Xfce WindowMaker IceWm Cde Jds OpenBox
bindings for LUA and C# dll
- License -
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef TINYFILEDIALOGS_H
#define TINYFILEDIALOGS_H
/* #define TINYFD_NOLIB */
/* On windows, define TINYFD_NOLIB here
if you don't want to include the code creating the graphic dialogs.
Then you won't need to link against Comdlg32.lib and Ole32.lib */
/* if tinydialogs.c is compiled with a C++ compiler rather than with a C compiler
(ie. you change the extension from .c to .cpp), you need to comment out:
extern "C" {
and the corresponding closing bracket near the end of this file:
}
*/
#ifdef __cplusplus
extern "C" {
#endif
extern char tinyfd_version[8]; /* contains tinyfd current version number */
#ifdef _WIN32
/* for UTF-16 use the functions at the end of this files */
extern int tinyfd_winUtf8; /* 0 (default) or 1 */
/* on windows string char can be 0:MBSC or 1:UTF-8
unless your code is really prepared for UTF-8 on windows, leave this on MBSC. */
#endif
extern int tinyfd_forceConsole ; /* 0 (default) or 1 */
/* for unix & windows: 0 (graphic mode) or 1 (console mode).
0: try to use a graphic solution, if it fails then it uses console mode.
1: forces all dialogs into console mode even when an X server is present,
if the package dialog (and a console is present) or dialog.exe is installed.
on windows it only make sense for console applications */
extern char tinyfd_response[1024];
/* if you pass "tinyfd_query" as aTitle,
the functions will not display the dialogs
but will return 0 for console mode, 1 for graphic mode.
tinyfd_response is then filled with the retain solution.
possible values for tinyfd_response are (all lowercase)
for the graphic mode:
windows applescript zenity zenity3 matedialog kdialog
xdialog tkinter gdialog gxmessage xmessage
for the console mode:
dialog whiptail basicinput */
int tinyfd_messageBox (
char const * const aTitle , /* "" */
char const * const aMessage , /* "" may contain \n \t */
char const * const aDialogType , /* "ok" "okcancel" "yesno" */
char const * const aIconType , /* "info" "warning" "error" "question" */
int const aDefaultButton ) ; /* 0 for cancel/no , 1 for ok/yes */
/* returns 0 for cancel/no , 1 for ok/yes */
char const * tinyfd_inputBox (
char const * const aTitle , /* "" */
char const * const aMessage , /* "" may NOT contain \n \t on windows */
char const * const aDefaultInput ) ; /* "" , if NULL it's a passwordBox */
/* returns NULL on cancel */
char const * tinyfd_saveFileDialog (
char const * const aTitle , /* "" */
char const * const aDefaultPathAndFile , /* "" */
int const aNumOfFilterPatterns , /* 0 */
char const * const * const aFilterPatterns , /* NULL | {"*.jpg","*.png"} */
char const * const aSingleFilterDescription ) ; /* NULL | "text files" */
/* returns NULL on cancel */
char const * tinyfd_openFileDialog (
char const * const aTitle , /* "" */
char const * const aDefaultPathAndFile , /* "" */
int const aNumOfFilterPatterns , /* 0 */
char const * const * const aFilterPatterns , /* NULL {"*.jpg","*.png"} */
char const * const aSingleFilterDescription , /* NULL | "image files" */
int const aAllowMultipleSelects ) ; /* 0 or 1 */
/* in case of multiple files, the separator is | */
/* returns NULL on cancel */
char const * tinyfd_selectFolderDialog (
char const * const aTitle , /* "" */
char const * const aDefaultPath ) ; /* "" */
/* returns NULL on cancel */
char const * tinyfd_colorChooser(
char const * const aTitle , /* "" */
char const * const aDefaultHexRGB , /* NULL or "#FF0000" */
unsigned char const aDefaultRGB[3] , /* { 0 , 255 , 255 } */
unsigned char aoResultRGB[3] ) ; /* { 0 , 0 , 0 } */
/* returns the hexcolor as a string "#FF0000" */
/* aoResultRGB also contains the result */
/* aDefaultRGB is used only if aDefaultHexRGB is NULL */
/* aDefaultRGB and aoResultRGB can be the same array */
/* returns NULL on cancel */
/************ NOT CROSS PLATFORM SECTION STARTS HERE ************************/
#ifdef _WIN32
#ifndef TINYFD_NOLIB
/* windows only - utf-16 version */
int tinyfd_messageBoxW(
wchar_t const * const aTitle ,
wchar_t const * const aMessage, /* "" may contain \n \t */
wchar_t const * const aDialogType, /* "ok" "okcancel" "yesno" */
wchar_t const * const aIconType, /* "info" "warning" "error" "question" */
int const aDefaultButton ); /* 0 for cancel/no , 1 for ok/yes */
/* returns 0 for cancel/no , 1 for ok/yes */
/* windows only - utf-16 version */
wchar_t const * tinyfd_saveFileDialogW(
wchar_t const * const aTitle, /* NULL or "" */
wchar_t const * const aDefaultPathAndFile, /* NULL or "" */
int const aNumOfFilterPatterns, /* 0 */
wchar_t const * const * const aFilterPatterns, /* NULL or {"*.jpg","*.png"} */
wchar_t const * const aSingleFilterDescription); /* NULL or "image files" */
/* returns NULL on cancel */
/* windows only - utf-16 version */
wchar_t const * tinyfd_openFileDialogW(
wchar_t const * const aTitle, /* "" */
wchar_t const * const aDefaultPathAndFile, /* "" */
int const aNumOfFilterPatterns , /* 0 */
wchar_t const * const * const aFilterPatterns, /* NULL {"*.jpg","*.png"} */
wchar_t const * const aSingleFilterDescription, /* NULL | "image files" */
int const aAllowMultipleSelects ) ; /* 0 or 1 */
/* in case of multiple files, the separator is | */
/* returns NULL on cancel */
/* windows only - utf-16 version */
wchar_t const * tinyfd_selectFolderDialogW(
wchar_t const * const aTitle, /* "" */
wchar_t const * const aDefaultPath); /* "" */
/* returns NULL on cancel */
/* windows only - utf-16 version */
wchar_t const * tinyfd_colorChooserW(
wchar_t const * const aTitle, /* "" */
wchar_t const * const aDefaultHexRGB, /* NULL or "#FF0000" */
unsigned char const aDefaultRGB[3] , /* { 0 , 255 , 255 } */
unsigned char aoResultRGB[3] ) ; /* { 0 , 0 , 0 } */
/* returns the hexcolor as a string "#FF0000" */
/* aoResultRGB also contains the result */
/* aDefaultRGB is used only if aDefaultHexRGB is NULL */
/* aDefaultRGB and aoResultRGB can be the same array */
/* returns NULL on cancel */
#endif /*TINYFD_NOLIB*/
#else /*_WIN32*/
/* unix zenity only */
char const * tinyfd_arrayDialog(
char const * const aTitle , /* "" */
int const aNumOfColumns , /* 2 */
char const * const * const aColumns, /* {"Column 1","Column 2"} */
int const aNumOfRows, /* 2*/
char const * const * const aCells);
/* {"Row1 Col1","Row1 Col2","Row2 Col1","Row2 Col2"} */
#endif /*_WIN32 */
#ifdef __cplusplus
}
#endif
#endif /* TINYFILEDIALOGS_H */
/*
- This is not for android nor ios.
- The code is pure C, perfectly compatible with C++.
- the utf-16 prototypes are in the header file
- The API is Fortran ISO_C_BINDING compliant
- C# via dll, see example file
- OSX supported from 10.4 to 10.11
- Avoid using " and ' in titles and messages.
- There's one file filter only, it may contain several patterns.
- If no filter description is provided,
the list of patterns will become the description.
- char const * filterPatterns[3] = { "*.obj" , "*.stl" , "*.dxf" } ;
- On windows link against Comdlg32.lib and Ole32.lib
This linking is not compulsary for console mode (see above).
- On unix: it tries command line calls, so no such need.
- On unix you need applescript, zenity, matedialog, kdialog, Xdialog,
python2/tkinter or dialog (will open a terminal if running without console).
- One of those is already included on most (if not all) desktops.
- In the absence of those it will use gdialog, gxmessage or whiptail
with a textinputbox.
- If nothing is found, it switches to basic console input,
it opens a console if needed.
- Use windows separators on windows and unix separators on unix.
- String memory is preallocated statically for all the returned values.
- File and path names are tested before return, they are valid.
- If you pass only a path instead of path + filename,
make sure it ends with a separator.
- tinyfd_forceConsole=1; at run time, forces dialogs into console mode.
- On windows, console mode only make sense for console applications.
- Mutiple selects are not allowed in console mode.
- The package dialog must be installed to run in enhanced console mode.
It is already installed on most unix systems.
- On osx, the package dialog can be installed via http://macports.org
- On windows, for enhanced console mode,
dialog.exe should be copied somewhere on your executable path.
It can be found at the bottom of the following page:
http://andrear.altervista.org/home/cdialog.php
- If dialog is missing, it will switch to basic console input.
- You can query the type of dialog that will be use.
- MinGW needs gcc >= v4.9 otherwise some headers are incomplete.
- The Hello World (and a bit more) is on the sourceforge site:
*/

7
src/examples/basic.c

@ -0,0 +1,7 @@
#include <lob.h>
int main()
{
lob(LOB_STDOUT, LOB_INFO, "Hello world!");
return 0;
}

18
src/examples/test.c

@ -0,0 +1,18 @@
#include <lob.h>
int main()
{
lob(LOB_STDOUT, LOB_ERROR, "Stderr Simple test");
lob(LOB_STDOUT, LOB_INFO, "Stdout Simple test");
lob(LOB_GUIBOX, LOB_INFO, "Guibox Simple test");
lob(LOB_FILE, LOB_INFO, "File Simple test");
char *str = "Bob Loblaw's law blog";
int i = 11;
lob(LOB_STDOUT | LOB_GUIBOX | LOB_FILE, LOB_ERROR, "Error |%s| |%i|", str, i);
lob(LOB_STDOUT | LOB_GUIBOX | LOB_FILE, LOB_WARN, "Warn |%s| |%i|", str, i);
lob(LOB_STDOUT | LOB_GUIBOX | LOB_FILE, LOB_INFO, "Info |%s| |%i|", str, i);
lob(LOB_STDOUT | LOB_GUIBOX | LOB_FILE, LOB_DEBUG, "Debug |%s| |%i|", str, i);
return 0;
}

215
src/lob.c

@ -0,0 +1,215 @@
/*
Copyright (c) 2016 Orangehattech, LLC
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.
*/
#include "lob.h"
// ***Includes***
#include <stdarg.h>
// ***Defines***
#ifdef LOB_TIME
#define LOB_TIME_STRINGLEN sizeof(LOB_TIME)
#endif
// ***Output Functions***
// They're void because, let's face it: If the error systems fails to error, what're we SUPPOSED to do?
#ifdef LOB_STDOUT
static inline void lob_out_stdout(const char *prefix, const char *time, const char *msg, va_list args)
{
printf("%s%s: ", prefix, time);
vprintf(msg, args);
printf("\n");
//In most situations, "\n" will flush.
//If we ever find something where that's not the case, the next line may be useful:
//fflush(stdout);
}
static inline void lob_out_stderr(const char *prefix, const char *time, const char *msg, va_list args)
{
fprintf(stderr, "%s%s: ", prefix, time);
vfprintf(stderr, msg, args);
fprintf(stderr, "\n");
//In most situations, "\n" will flush.
//If we ever find something where that's not the case, the next line may be useful:
//fflush(stderr);
}
#endif
#ifdef LOB_FILE
//On many platforms, writes to unclosed files may not show up.
//To combat this, we open and close the file each time we write.
//This also means no shared state in lob
static inline void lob_out_file(const char *prefix, const char level, const char *time, const char *msg, va_list args)
{
FILE *file;
switch (level)
{
case LOB_ERROR:
file = fopen(LOB_FILE_ERROR, "a+");
break;
case LOB_WARN:
file = fopen(LOB_FILE_WARN, "a+");
break;
case LOB_INFO:
file = fopen(LOB_FILE_INFO, "a+");
break;
case LOB_DEBUG:
file = fopen(LOB_FILE_DEBUG, "a+");
break;
}
if (file == NULL)
return; //couldn't open file, just give up
fprintf(file, "%s%s: ", prefix, time);
vfprintf(file, msg, args);
fprintf(file, "\n");
fclose(file);
}
#endif
#ifdef LOB_GUIBOX
static inline char* lob_msg_getlevel(const char level)
{
switch(level)
{
case LOB_ERROR:
return "error";
break;
case LOB_WARN:
return "warn";
break;
case LOB_INFO:
case LOB_DEBUG:
default:
return "info";
break;
}
}
static inline void lob_out_msg(const char *prefix, const char level, char *buffer, const char *msg, va_list args)
{
vsnprintf(buffer, LOB_MAX_BUFFER_SIZE, msg, args);
tinyfd_messageBox(LOB_GUIBOX_NAME, buffer, "ok", lob_msg_getlevel(level), 1);
}
#endif
#ifdef LOB_NET
static inline void lob_out_net(const char *prefix, const char *time, const char *msg, va_list args)
{
}
#endif
#ifdef LOB_SYSLOG
//Do we need to pass time here, or is that something syslog appends?
static inline void lob_out_syslog(const char *prefix, const char *msg, va_list args)
{
}
#endif
// ***Internal Functions***
static inline char* lob_get_prefix(const char level)
{
#ifdef LOB_PREFIX
switch(level)
{
case LOB_ERROR:
return LOB_PREFIX_ERROR;
break;
case LOB_WARN:
return LOB_PREFIX_WARN;
break;
case LOB_INFO:
return LOB_PREFIX_INFO;
break;
case LOB_DEBUG:
return LOB_PREFIX_DEBUG;
break;
default:
//This should never happen. I hope.
return "Oops";
break;
}
#endif
return "";
}
//Will not touch the string unless LOB_TIME is enabled
static inline void lob_get_time(char *timeString)
{
#ifdef LOB_TIME
time_t current_time;
struct tm * time_info;
time(&current_time);
time_info = localtime(&current_time);
strftime(timeString, LOB_TIME_STRINGLEN, LOB_TIME, time_info);
#endif
}
// ***External Functions***
extern char lob(const unsigned char flags, const char level, const char *msg, ...)
{
char *prefix = lob_get_prefix(level);
char time[LOB_TIME_STRINGLEN] = "";
lob_get_time(time);
va_list args;
#ifdef LOB_STDOUT
if (flags & LOB_STDOUT)
{
va_start(args, msg);
if (level <= LOB_STDOUT_STDERR)
lob_out_stderr(prefix, time, msg, args);
else
lob_out_stdout(prefix, time, msg, args);
va_end(args);
}
#endif
#ifdef LOB_FILE
if (flags & LOB_FILE)
{
va_start(args, msg);
lob_out_file(prefix, level, time, msg, args);
va_end(args);
}
#endif
#ifdef LOB_GUIBOX
//We use buffer as a quick shorthand, so we don't need to test both it AND the flags(again)
if (flags & LOB_GUIBOX)
{
char *buffer = calloc(LOB_MAX_BUFFER_SIZE, sizeof(char));
if (buffer == NULL)
return level; //Couldn't allocate - Just give up.
va_start(args, msg);
lob_out_msg(prefix, level, buffer, msg, args);
va_end(args);
free(buffer);
}
#endif
return level;
}
extern char loblvl(const char minLevel, const unsigned char flags, const char level, const char *msg, ...)
{
// if (minLevel >= level)
// return lob(flags, level, msg, ...);
return level;
}

68
src/lob.h

@ -0,0 +1,68 @@
/*
Copyright (c) 2016 Orangehattech, LLC
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.
*/
// ***Include guards***
#pragma once //Speeds up compilation on platforms that support it
#ifndef LOB_INCLUDED
#define LOB_INCLUDED
#include "lobtions.h"
// ***Specific includes***
#ifdef LOB_DATE
#error Date isn't implemented yet. Sorry!
// #include <time.h>
#endif
#ifdef LOB_TIME
#include <time.h>
#endif
#ifdef LOB_STDOUT
#include <stdio.h>
#endif
#ifdef LOB_FILE
#include <stdio.h>
#endif
#ifdef LOB_GUIBOX
#include <stdlib.h>
#include "tinyfiledialogs.h" //Cross platform reliable UI boxes.
#endif
#ifdef LOB_NET
#error Network logging isn't implemented yet. Sorry!
#endif
#ifdef LOB_SYSLOG
#error System logging isn't implemented yet. Sorry!
#endif
// ***Log Levels***
//We use powers of two in case a library user wants to do some fancy bitflag stuff.
#define LOB_ERROR 1
#define LOB_WARN 2
#define LOB_INFO 4
#define LOB_DEBUG 8
// ***External Functions***
//Returns whatever message level was passed to it.
extern char lob(const unsigned char, const char, const char *, ...);
//Will call lob only if the level is lower than the first argument.
//This allows users to change the minimum level of output at runtime
//Returns whatever message level was passed to it.
//extern char loblvl(const char, const unsigned char, const char, const char *, ...);
//Unimplemented
//Calls lob or loblvl in addition to doing user callback
//typedef lob_callback
//extern char lobcb(const unsigned char, const char, const char *, ..., );
//extern char lobcblvl(const char, const unsigned char, const char, const char *, ...);
// ***Include guards***
#endif

46
src/lobtions.h

@ -0,0 +1,46 @@
//This file is used to specify how lob works
//Any #define in this file can also be passed via -D to the compiler
//lobtions.h can either be considered under the MIT license or public domain.
// ***Optional fields***
// Enable/disable by commenting
#define LOB_TIME "[%H:%M:%S] "
#define LOB_PREFIX
// ***Output methods***
// Enable/disable by commenting
#define LOB_STDOUT 1
#define LOB_FILE 2
#define LOB_GUIBOX 4
//#define LOB_NET 8
//#define LOB_SYSLOG 16
// ***Level Prefix Strings***
// Not used in all output types
#define LOB_PREFIX_ERROR "<*ERR> "
#define LOB_PREFIX_WARN "<Warn> "
#define LOB_PREFIX_INFO "<Info> "
#define LOB_PREFIX_DEBUG "<Debg> "
// ***LOB_STDOUT options***
// Log levels <= than this will go to stderr instead of stdout
// Must be 0, LOB_ERROR, LOB_WARN, LOB_INFO, or LOB_DEBUG
#define LOB_STDOUT_STDERR LOB_ERROR
// ***LOB_FILE options***
// Which files to write each level to
// Path is relative to the running binary
// Note - lob only ever appends to this file, never overwrites.
#define LOB_FILE_ERROR "log.txt"
#define LOB_FILE_WARN "log.txt"
#define LOB_FILE_INFO "log.txt"
#define LOB_FILE_DEBUG "log.txt"
// ***LOB_GUIBOX options***
// 'prefix' means it will inherit from LOB_PREFIX_*
// Otherwise, a literal string is required: "Example"
#define LOB_GUIBOX_NAME prefix
// Currently only GUIBOX needs buffers
// Messages longer than this size will be truncated
#define LOB_MAX_BUFFER_SIZE 4096

4
test

@ -0,0 +1,4 @@
#!/bin/bash
make clean
clear
make test && ./bin/test
Loading…
Cancel
Save