summaryrefslogtreecommitdiff
path: root/src/console.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/console.c')
-rw-r--r--src/console.c613
1 files changed, 308 insertions, 305 deletions
diff --git a/src/console.c b/src/console.c
index b05f0a3..07e3c37 100644
--- a/src/console.c
+++ b/src/console.c
@@ -1,6 +1,6 @@
/*
Copyright (c) 2015
- Michał Cichoń <thedmd@interia.pl>
+ Michał Cichoń <thedmd@interia.pl>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -29,392 +29,395 @@ THE SOFTWARE.
#include <process.h>
#include "vtparse/vtparse.h"
-enum { READ = 0, WRITE };
-
-# define BAR_IN_CAPACITY 1024
-# define BAR_OUT_CAPACITY 1024
+# define BAR_BUFFER_CAPACITY 1024
static const int BarTerminalToAttibColor[8] = {
- 0 /* black */, 4 /* red */, 2 /* green */, 6 /* yellow */,
- 1 /* blue */, 5 /* magenta */, 3 /* cyan */, 7 /* white */
+ 0 /* black */, 4 /* red */, 2 /* green */, 6 /* yellow */,
+ 1 /* blue */, 5 /* magenta */, 3 /* cyan */, 7 /* white */
};
-static struct BarConsoleState {
- HANDLE StdIn;
- HANDLE StdOut;
-
- int Pipes[2];
- int OriginalStdOut;
- int OriginalStdErr;
-
- WORD DefaultAttributes;
- WORD CurrentAttributes;
+static struct BarConsoleState
+{
+ HANDLE StdIn;
+ HANDLE StdOut;
- HANDLE ConsoleThread;
- bool Terminate;
+ WORD DefaultAttributes;
+ WORD CurrentAttributes;
- vtparse_t Parser;
+ HANDLE ConsoleThread;
+ bool Terminate;
- char InBuffer[BAR_IN_CAPACITY];
- size_t InBufferSize;
+ vtparse_t Parser;
- char OutBuffer[BAR_OUT_CAPACITY];
- size_t OutBufferSize;
+ char Buffer[BAR_BUFFER_CAPACITY];
+ size_t BufferSize;
} g_BarConsole;
-static inline void BarOutSetAttributes(WORD attributes) {
- g_BarConsole.CurrentAttributes = attributes;
- SetConsoleTextAttribute(CONSOLE_REAL_OUTPUT_HANDLE, g_BarConsole.CurrentAttributes);
+static inline void BarOutSetAttributes(WORD attributes)
+{
+ g_BarConsole.CurrentAttributes = attributes;
+ SetConsoleTextAttribute(BarConsoleGetStdOut(), g_BarConsole.CurrentAttributes);
}
-static inline void BarOutFlush() {
- if (g_BarConsole.OutBufferSize == 0)
- return;
+static void BarParseCallback(struct vtparse* parser, vtparse_action_t action, unsigned char ch)
+{
+ if (action == VTPARSE_ACTION_PRINT || action == VTPARSE_ACTION_EXECUTE)
+ {
+ putc(ch, stdout);
+ if (action == VTPARSE_ACTION_EXECUTE)
+ fflush(stdout);
+ }
+
+ if (action == VTPARSE_ACTION_CSI_DISPATCH)
+ {
+ WORD attribute = g_BarConsole.CurrentAttributes;
+ int i;
+
+ switch (ch)
+ {
+ case 'K':
+ BarConsoleEraseLine(parser->num_params > 0 ? parser->params[0] : 0);
+ break;
+
+ case 'm':
+ for (i = 0; i < parser->num_params; ++i)
+ {
+ int p = parser->params[i];
+ if (p == 0)
+ attribute = g_BarConsole.DefaultAttributes;
+ //else if (p == 1)
+ // attribute |= FOREGROUND_INTENSITY;
+ else if (p == 4)
+ attribute |= COMMON_LVB_UNDERSCORE;
+ else if (p == 7)
+ attribute |= COMMON_LVB_REVERSE_VIDEO;
+ //else if (p == 21)
+ // attribute &= ~FOREGROUND_INTENSITY;
+ else if (p == 24)
+ attribute &= ~COMMON_LVB_UNDERSCORE;
+ else if (p == 27)
+ attribute &= ~COMMON_LVB_REVERSE_VIDEO;
+ else if (p >= 30 && p <= 37)
+ attribute = (attribute & ~0x07) | BarTerminalToAttibColor[p - 30];
+ else if (p >= 40 && p <= 47)
+ attribute = (attribute & ~0x70) | (BarTerminalToAttibColor[p - 40] << 4);
+ else if (p >= 90 && p <= 97)
+ attribute = (attribute & ~0x07) | BarTerminalToAttibColor[p - 90] | FOREGROUND_INTENSITY;
+ else if (p >= 100 && p <= 107)
+ attribute = ((attribute & ~0x70) | (BarTerminalToAttibColor[p - 100] << 4)) | BACKGROUND_INTENSITY;
+ }
+ fflush(stdout);
+ BarOutSetAttributes(attribute);
+ break;
+ }
+ }
+}
- _write(g_BarConsole.OriginalStdOut, g_BarConsole.OutBuffer, g_BarConsole.OutBufferSize);
+void BarConsoleInit()
+{
+ unsigned threadId = 0;
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+ memset(&g_BarConsole, 0, sizeof(g_BarConsole));
- g_BarConsole.OutBufferSize = 0;
-}
+ SetConsoleCP(CP_UTF8);
+ SetConsoleOutputCP(CP_UTF8);
-static inline void BarOutPut(char c) {
- if (g_BarConsole.OutBufferSize >= BAR_OUT_CAPACITY)
- BarOutFlush();
+ g_BarConsole.StdIn = GetStdHandle(STD_INPUT_HANDLE);
+ g_BarConsole.StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
- g_BarConsole.OutBuffer[g_BarConsole.OutBufferSize++] = c;
-}
+ GetConsoleScreenBufferInfo(g_BarConsole.StdOut, &csbi);
-static inline void BarOutPuts(const char* c) {
- size_t length = strlen(c);
- size_t i;
+ g_BarConsole.DefaultAttributes = csbi.wAttributes;
+ g_BarConsole.CurrentAttributes = csbi.wAttributes;
- for (i = 0; i < length; ++i)
- BarOutPut(c[i]);
+ vtparse_init(&g_BarConsole.Parser, BarParseCallback);
}
-static void BarParseCallback(struct vtparse* parser, vtparse_action_t action, unsigned char ch) {
- if (action == VTPARSE_ACTION_PRINT || action == VTPARSE_ACTION_EXECUTE)
- {
- BarOutPut(ch);
- if (action == VTPARSE_ACTION_EXECUTE)
- BarOutFlush();
- }
-
- if (action == VTPARSE_ACTION_CSI_DISPATCH)
- {
- WORD attribute = g_BarConsole.CurrentAttributes;
- int i;
-
- switch (ch)
- {
- case 'K':
- BarConsoleEraseLine(parser->num_params > 0 ? parser->params[0] : 0);
- break;
-
- case 'm':
- for (i = 0; i < parser->num_params; ++i) {
- int p = parser->params[i];
- if (p == 0)
- attribute = g_BarConsole.DefaultAttributes;
- //else if (p == 1)
- // attribute |= FOREGROUND_INTENSITY;
- else if (p == 4)
- attribute |= COMMON_LVB_UNDERSCORE;
- else if (p == 7)
- attribute |= COMMON_LVB_REVERSE_VIDEO;
- //else if (p == 21)
- // attribute &= ~FOREGROUND_INTENSITY;
- else if (p == 24)
- attribute &= ~COMMON_LVB_UNDERSCORE;
- else if (p == 27)
- attribute &= ~COMMON_LVB_REVERSE_VIDEO;
- else if (p >= 30 && p <= 37)
- attribute = (attribute & ~0x07) | BarTerminalToAttibColor[p - 30];
- else if (p >= 40 && p <= 47)
- attribute = (attribute & ~0x70) | (BarTerminalToAttibColor[p - 40] << 4);
- else if (p >= 90 && p <= 97)
- attribute = (attribute & ~0x07) | BarTerminalToAttibColor[p - 90] | FOREGROUND_INTENSITY;
- else if (p >= 100 && p <= 107)
- attribute = ((attribute & ~0x70) | (BarTerminalToAttibColor[p - 100] << 4)) | BACKGROUND_INTENSITY;
- }
- BarOutFlush();
- BarOutSetAttributes(attribute);
- break;
- }
- }
+void BarConsoleDestroy()
+{
}
-static unsigned __stdcall BarConsoleThread(void* args) {
-
- while (!g_BarConsole.Terminate) {
+HANDLE BarConsoleGetStdIn()
+{
+ return g_BarConsole.StdIn;
+}
- int bytes = _read(g_BarConsole.Pipes[READ], g_BarConsole.InBuffer, BAR_IN_CAPACITY);
+HANDLE BarConsoleGetStdOut()
+{
+ return g_BarConsole.StdOut;
+}
- if (bytes > 0)
- vtparse(&g_BarConsole.Parser, g_BarConsole.InBuffer, bytes);
+void BarConsoleSetTitle(const char* title)
+{
+ size_t len = MultiByteToWideChar(CP_UTF8, 0, title, -1, NULL, 0);
- BarOutFlush();
- }
+ TCHAR* wTitle = malloc((len + 1) * sizeof(TCHAR));
+ if (NULL != wTitle)
+ {
+ MultiByteToWideChar(CP_UTF8, 0, title, -1, wTitle, len);
+ SetConsoleTitleW(wTitle);
- return 0;
+ free(wTitle);
+ }
+ else
+ SetConsoleTitleA(title);
}
-void BarConsoleInit() {
- unsigned threadId = 0;
- CONSOLE_SCREEN_BUFFER_INFO csbi;
- memset(&g_BarConsole, 0, sizeof(g_BarConsole));
+void BarConsoleSetSize(int width, int height)
+{
+ HANDLE handle;
+ SMALL_RECT r;
+ COORD c, s;
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
- SetConsoleCP(CP_UTF8);
- SetConsoleOutputCP(CP_UTF8);
+ handle = BarConsoleGetStdOut();
- g_BarConsole.StdIn = GetStdHandle(STD_INPUT_HANDLE);
- g_BarConsole.StdOut = GetStdHandle(STD_OUTPUT_HANDLE);
+ if (!GetConsoleScreenBufferInfo(handle, &csbi))
+ return;
- GetConsoleScreenBufferInfo(g_BarConsole.StdOut, &csbi);
+ s.X = csbi.srWindow.Right - csbi.srWindow.Left + 1;
+ s.Y = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
- g_BarConsole.DefaultAttributes = csbi.wAttributes;
- g_BarConsole.CurrentAttributes = csbi.wAttributes;
+ if (s.X > width && s.Y > height)
+ return;
- if (_pipe(g_BarConsole.Pipes, 65536, O_BINARY) != -1) {
- g_BarConsole.OriginalStdOut = _dup(_fileno(stdout));
- g_BarConsole.OriginalStdErr = _dup(_fileno(stderr));
+ c.X = width;
+ c.Y = height;
- fflush(stdout);
- fflush(stderr);
+ if (s.X > c.X)
+ c.X = s.X;
+ if (s.Y > c.Y)
+ c.Y = s.Y;
- dup2(g_BarConsole.Pipes[WRITE], fileno(stdout));
- dup2(g_BarConsole.Pipes[WRITE], fileno(stderr));
+ SetConsoleScreenBufferSize(handle, c);
- g_BarConsole.ConsoleThread = (HANDLE)_beginthreadex(NULL, 0, BarConsoleThread, NULL, 0, &threadId);
- if (!g_BarConsole.ConsoleThread)
- BarConsoleDestroy();
- }
-
- vtparse_init(&g_BarConsole.Parser, BarParseCallback);
+ r.Left = 0;
+ r.Top = 0;
+ r.Right = c.X - 1;
+ r.Bottom = c.Y - 1;
+ SetConsoleWindowInfo(handle, TRUE, &r);
}
-void BarConsoleDestroy() {
- if (g_BarConsole.ConsoleThread) {
- g_BarConsole.Terminate = true;
- fputs(" ", stderr);
- fputs(" ", stdout);
-
- fflush(stdout);
- fflush(stderr);
-
- WaitForSingleObject(g_BarConsole.ConsoleThread, INFINITE);
- }
-
- if (g_BarConsole.OriginalStdErr > 0) {
- fflush(stderr);
- dup2(g_BarConsole.OriginalStdErr, fileno(stderr));
- _close(g_BarConsole.OriginalStdErr);
- g_BarConsole.OriginalStdErr = 0;
- }
- if (g_BarConsole.OriginalStdOut > 0) {
- fflush(stdout);
- dup2(g_BarConsole.OriginalStdOut, fileno(stdout));
- _close(g_BarConsole.OriginalStdOut);
- g_BarConsole.OriginalStdOut = 0;
- }
- if (g_BarConsole.Pipes[0] > 0) {
- _close(g_BarConsole.Pipes[0]);
- g_BarConsole.Pipes[0] = 0;
- }
- if (g_BarConsole.Pipes[1] > 0) {
- _close(g_BarConsole.Pipes[1]);
- g_BarConsole.Pipes[1] = 0;
- }
+void BarConsoleSetCursorPosition(COORD position)
+{
+ SetConsoleCursorPosition(BarConsoleGetStdOut(), position);
}
-HANDLE BarConsoleGetStdIn () {
- return g_BarConsole.StdIn;
-}
+COORD BarConsoleGetCursorPosition()
+{
+ CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
+ COORD result = { -1, -1 };
+
+ if (GetConsoleScreenBufferInfo(BarConsoleGetStdOut(), &consoleInfo))
+ result = consoleInfo.dwCursorPosition;
-HANDLE BarConsoleGetStdOut () {
- return GetStdHandle(STD_OUTPUT_HANDLE);//g_BarConsole.StdOut;
+ return result;
}
-void BarConsoleSetTitle (const char* title) {
- size_t len = MultiByteToWideChar (CP_UTF8, 0, title, -1, NULL, 0);
+COORD BarConsoleMoveCursor(int xoffset)
+{
+ COORD position;
- TCHAR* wTitle = malloc((len + 1) * sizeof(TCHAR));
- if (NULL != wTitle)
- {
- MultiByteToWideChar (CP_UTF8, 0, title, -1, wTitle, len);
- SetConsoleTitleW (wTitle);
+ position = BarConsoleGetCursorPosition();
+ position.X += xoffset;
+ BarConsoleSetCursorPosition(position);
- free(wTitle);
- }
- else
- SetConsoleTitleA (title);
+ return position;
}
-void BarConsoleSetSize (int width, int height) {
- HANDLE handle;
- SMALL_RECT r;
- COORD c, s;
- CONSOLE_SCREEN_BUFFER_INFO csbi;
+void BarConsoleEraseCharacter()
+{
+ TCHAR buffer[256];
+ WORD buffer2[256];
+ CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
+ COORD coords;
+ HANDLE handle = BarConsoleGetStdOut();
+ int length, read, write;
+
+ if (!GetConsoleScreenBufferInfo(handle, &csbiInfo))
+ return;
+
+ length = csbiInfo.dwSize.X - csbiInfo.dwCursorPosition.X - 1;
+ read = csbiInfo.dwCursorPosition.X + 1;
+ write = csbiInfo.dwCursorPosition.X;
+
+ while (length >= 0)
+ {
+ int size = min(length, 256);
+ DWORD chRead = 0, chWritten = 0;
+ coords = csbiInfo.dwCursorPosition;
+ coords.X = read;
+ ReadConsoleOutputAttribute(handle, buffer2, size, coords, &chRead);
+ ReadConsoleOutputCharacter(handle, buffer, size, coords, &chRead);
+
+ if (chRead == 0)
+ break;
+
+ coords.X = write;
+ WriteConsoleOutputAttribute(handle, buffer2, chRead, coords, &chWritten);
+ WriteConsoleOutputCharacter(handle, buffer, chRead, coords, &chWritten);
+
+ read += chRead;
+ write += chRead;
+ length -= chRead;
+ }
+}
- handle = CONSOLE_REAL_OUTPUT_HANDLE;
+void BarConsoleEraseLine(int mode)
+{
+ CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
+ DWORD writen, length;
+ COORD coords;
- if (!GetConsoleScreenBufferInfo(handle, &csbi))
- return;
+ HANDLE handle = BarConsoleGetStdOut();
- s.X = csbi.srWindow.Right - csbi.srWindow.Left + 1;
- s.Y = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
+ if (!GetConsoleScreenBufferInfo(handle, &csbiInfo))
+ return;
- if (s.X > width && s.Y > height)
- return;
+ writen = 0;
+ coords.X = 0;
+ coords.Y = csbiInfo.dwCursorPosition.Y;
- c.X = width;
- c.Y = height;
+ switch (mode)
+ {
+ default:
+ case 0: /* from cursor */
+ coords.X = BarConsoleGetCursorPosition().X;
+ length = csbiInfo.dwSize.X - coords.X;
+ break;
- if (s.X > c.X)
- c.X = s.X;
- if (s.Y > c.Y)
- c.Y = s.Y;
+ case 1: /* to cursor */
+ coords.X = 0;
+ length = BarConsoleGetCursorPosition().X;
+ break;
- SetConsoleScreenBufferSize(handle, c);
+ case 2: /* whole line */
+ coords.X = 0;
+ length = csbiInfo.dwSize.X;
+ break;
+ }
- r.Left = 0;
- r.Top = 0;
- r.Right = c.X - 1;
- r.Bottom = c.Y - 1;
- SetConsoleWindowInfo(handle, TRUE, &r);
-}
+ FillConsoleOutputCharacter(handle, ' ', length, coords, &writen);
+ FillConsoleOutputAttribute(handle, csbiInfo.wAttributes, csbiInfo.dwSize.X, coords, &writen);
-void BarConsoleSetCursorPosition (COORD position) {
- SetConsoleCursorPosition(CONSOLE_REAL_OUTPUT_HANDLE, position);
+ SetConsoleCursorPosition(handle, coords);
}
-COORD BarConsoleGetCursorPosition () {
- CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
- COORD result = { -1, -1 };
+void BarConsoleSetClipboard(const char* text)
+{
+ WCHAR* wideString;
+ HANDLE stringHandle;
+ size_t wideSize, wideBytes;
- if (GetConsoleScreenBufferInfo(CONSOLE_REAL_OUTPUT_HANDLE, &consoleInfo))
- result = consoleInfo.dwCursorPosition;
+ wideSize = MultiByteToWideChar(CP_UTF8, 0, text, -1, NULL, 0);
+ wideBytes = wideSize * sizeof(WCHAR);
+ wideString = malloc(wideBytes);
+ if (!wideString)
+ return;
- return result;
-}
+ MultiByteToWideChar(CP_UTF8, 0, text, -1, wideString, wideSize);
-COORD BarConsoleMoveCursor (int xoffset) {
- COORD position;
+ stringHandle = GlobalAlloc(GMEM_MOVEABLE, wideBytes);
+ if (!stringHandle)
+ {
+ free(wideString);
+ return;
+ }
- position = BarConsoleGetCursorPosition();
- position.X += xoffset;
- BarConsoleSetCursorPosition(position);
+ memcpy(GlobalLock(stringHandle), wideString, wideBytes);
- return position;
-}
+ GlobalUnlock(stringHandle);
-void BarConsoleEraseCharacter () {
- TCHAR buffer[256];
- WORD buffer2[256];
- CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
- COORD coords;
- HANDLE handle = CONSOLE_REAL_OUTPUT_HANDLE;
- int length, read, write;
-
- if (!GetConsoleScreenBufferInfo(handle, &csbiInfo))
- return;
-
- length = csbiInfo.dwSize.X - csbiInfo.dwCursorPosition.X - 1;
- read = csbiInfo.dwCursorPosition.X + 1;
- write = csbiInfo.dwCursorPosition.X;
-
- while (length >= 0) {
- int size = min(length, 256);
- DWORD chRead = 0, chWritten = 0;
- coords = csbiInfo.dwCursorPosition;
- coords.X = read;
- ReadConsoleOutputAttribute(handle, buffer2, size, coords, &chRead);
- ReadConsoleOutputCharacter(handle, buffer, size, coords, &chRead);
-
- if (chRead == 0)
- break;
-
- coords.X = write;
- WriteConsoleOutputAttribute(handle, buffer2, chRead, coords, &chWritten);
- WriteConsoleOutputCharacter(handle, buffer, chRead, coords, &chWritten);
-
- read += chRead;
- write += chRead;
- length -= chRead;
- }
-}
+ if (!OpenClipboard(NULL))
+ {
+ GlobalFree(stringHandle);
+ free(wideString);
+ return;
+ }
-void BarConsoleEraseLine (int mode) {
- CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
- DWORD writen, length;
- COORD coords;
+ EmptyClipboard();
- HANDLE handle = CONSOLE_REAL_OUTPUT_HANDLE;
+ SetClipboardData(CF_UNICODETEXT, stringHandle);
- if (!GetConsoleScreenBufferInfo(handle, &csbiInfo))
- return;
+ CloseClipboard();
- writen = 0;
- coords.X = 0;
- coords.Y = csbiInfo.dwCursorPosition.Y;
+ free(wideString);
+}
- switch (mode) {
- default:
- case 0: /* from cursor */
- coords.X = BarConsoleGetCursorPosition().X;
- length = csbiInfo.dwSize.X - coords.X;
- break;
+void BarConsoleFlush()
+{
+ char buffer[BAR_BUFFER_CAPACITY];
+ size_t bufferSize = 0;
- case 1: /* to cursor */
- coords.X = 0;
- length = BarConsoleGetCursorPosition().X;
- break;
+ if (g_BarConsole.BufferSize == 0)
+ return;
- case 2: /* whole line */
- coords.X = 0;
- length = csbiInfo.dwSize.X;
- break;
- }
+ bufferSize = g_BarConsole.BufferSize;
+ memcpy(buffer, g_BarConsole.Buffer, bufferSize);
- FillConsoleOutputCharacter(handle, ' ', length, coords, &writen);
- FillConsoleOutputAttribute(handle, csbiInfo.wAttributes, csbiInfo.dwSize.X, coords, &writen);
+ g_BarConsole.BufferSize = 0;
- SetConsoleCursorPosition(handle, coords);
+ vtparse(&g_BarConsole.Parser, buffer, bufferSize);
}
-void BarConsoleSetClipboard(const char* text) {
- WCHAR* wideString;
- HANDLE stringHandle;
- size_t wideSize, wideBytes;
+void BarConsolePutc(char c)
+{
+ if (g_BarConsole.BufferSize >= BAR_BUFFER_CAPACITY)
+ BarConsoleFlush();
- wideSize = MultiByteToWideChar(CP_UTF8, 0, text, -1, NULL, 0);
- wideBytes = wideSize * sizeof(WCHAR);
- wideString = malloc(wideBytes);
- if (!wideString)
- return;
-
- MultiByteToWideChar(CP_UTF8, 0, text, -1, wideString, wideSize);
+ g_BarConsole.Buffer[g_BarConsole.BufferSize++] = c;
+}
- stringHandle = GlobalAlloc(GMEM_MOVEABLE, wideBytes);
- if (!stringHandle) {
- free(wideString);
- return;
- }
+void BarConsolePuts(const char* c)
+{
+ size_t length = strlen(c);
+ size_t i;
- memcpy(GlobalLock(stringHandle), wideString, wideBytes);
+ for (i = 0; i < length; ++i)
+ BarConsolePutc(c[i]);
+}
- GlobalUnlock(stringHandle);
+static char* BarConsoleFormat(char* buffer, size_t buffer_size, const char* format, va_list args)
+{
+ bool allocated = false;
+
+ int chars_writen;
+ while ((chars_writen = _vsnprintf(buffer, buffer_size - 1, format, args)) < 0)
+ {
+ size_t new_buffer_size = buffer_size * 3 / 2;
+ if (new_buffer_size < buffer_size)
+ { // handle overflow
+ chars_writen = buffer_size;
+ break;
+ }
+
+ if (allocated)
+ buffer = realloc(buffer, new_buffer_size);
+ else
+ buffer = malloc(new_buffer_size);
+ buffer_size = new_buffer_size;
+ }
+
+ return buffer;
+}
- if (!OpenClipboard(NULL)) {
- GlobalFree(stringHandle);
- free(wideString);
- return;
- }
+void BarConsolePrint(const char* format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ BarConsolePrintV(format, args);
+ va_end(args);
+}
- EmptyClipboard();
+void BarConsolePrintV(const char* format, va_list args)
+{
+ char localBuffer[BAR_BUFFER_CAPACITY];
+ size_t bufferSize = BAR_BUFFER_CAPACITY, i = 0;
- SetClipboardData(CF_UNICODETEXT, stringHandle);
+ char* buffer = BarConsoleFormat(localBuffer, bufferSize, format, args);
- CloseClipboard();
+ BarConsolePuts(buffer);
- free(wideString);
+ if (buffer != localBuffer)
+ free(buffer);
} \ No newline at end of file