Last active
August 29, 2015 14:10
-
-
Save M-griffin/63f711bcffbc344f7eae to your computer and use it in GitHub Desktop.
Pipe Codes to ANSI Color ESC sequences
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Pipe Code to ANSI Color Parser | |
// Michael Griffin (c) 2011 | |
// Donated to DayDream BBS in C, Rework of Enthral BBS from C++ | |
// Compile using gcc in in linux. | |
// Free to use and modify | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
// Ansi Forground Escape Sequences | |
void ansi_fg(char *data, int fg) | |
{ | |
switch (fg) | |
{ | |
case 0: | |
strcat(data, "x[0;30m"); | |
break; | |
case 1: | |
strcat(data, "x[0;34m"); | |
break; | |
case 2: | |
strcat(data, "x[0;32m"); | |
break; | |
case 3: | |
strcat(data, "x[0;36m"); | |
break; | |
case 4: | |
strcat(data, "x[0;31m"); | |
break; | |
case 5: | |
strcat(data, "x[0;35m"); | |
break; | |
case 6: | |
strcat(data, "x[0;33m"); | |
break; | |
case 7: | |
strcat(data, "x[0;37m"); | |
break; | |
case 8: | |
strcat(data, "x[1;30m"); | |
break; | |
case 9: | |
strcat(data, "x[1;34m"); | |
break; | |
case 10: | |
strcat(data, "x[1;32m"); | |
break; | |
case 11: | |
strcat(data, "x[1;36m"); | |
break; | |
case 12: | |
strcat(data, "x[1;31m"); | |
break; | |
case 13: | |
strcat(data, "x[1;35m"); | |
break; | |
case 14: | |
strcat(data, "x[1;33m"); | |
break; | |
case 15: | |
strcat(data, "x[1;37m"); | |
break; | |
default : | |
break; | |
} | |
data[0] = '\x1b'; | |
} | |
// Ansi Background Escape Sequences | |
void ansi_bg(char *data, int bg) | |
{ | |
switch (bg) | |
{ | |
case 16: | |
strcat(data, "x[40m"); | |
break; | |
case 17: | |
strcat(data, "x[44m"); | |
break; | |
case 18: | |
strcat(data, "x[42m"); | |
break; | |
case 19: | |
strcat(data, "x[46m"); | |
break; | |
case 20: | |
strcat(data, "x[41m"); | |
break; | |
case 21: | |
strcat(data, "x[45m"); | |
break; | |
case 22: | |
strcat(data, "x[43m"); | |
break; | |
case 23: | |
strcat(data, "x[47m"); | |
break; | |
// Default to none. | |
case 24: | |
strcat(data, "x[0m"); | |
break; | |
default : | |
break; | |
} | |
data[0] = '\x1b'; | |
} | |
// Pipe2Ansi, parses all |01 - |23 codes | |
void pipe2ansi(char* szString) | |
{ | |
// These should really be dynamic to handle any size. | |
char szReplace[10] = {0}; // Holds Ansi String Sequence, no longer then 10 | |
// If we parse other data can make this bigger | |
char *szStrBuilder; // Holds new String being built | |
// We dynamically allocate this so we never | |
// Run out of space when building the new string. | |
int size = strlen(szString); // get size of string we are parsing, | |
int index = 0; // Index of Pipe Char in String | |
char* pch; // Pointer to Pipe Char in String if found | |
// Generic Counters | |
int i = 0; | |
int j = 0; | |
// Search Initial String for Pipe Char, if not found exit, else continue | |
pch = (char *) memchr (szString, '|', size); | |
if (pch != NULL) | |
{ | |
// Calculate Index Position of | char found in string. | |
index = pch-szString; | |
//printf("Pipe Code found!: %d, size %d \r\n", index, size); | |
} | |
else | |
{ | |
// No Pipe Code in String | |
// no need to test further, so return | |
return; | |
} | |
// Setup Loop through String to test and replace pipe codes with | |
// Ansi ESC Sequences. | |
for ( ; index < size; index++) | |
{ | |
// Make sure pipe can't possibly extend past the end of the string. | |
// End of String reached, no possiable pipe code. | |
if (index +2 >= size) | |
return; | |
// Test if Current Index is a Pipe Code. | |
if (szString[index] == '|') | |
{ | |
// Each loop, clear out Char Array to start with fresh ansi string. | |
memset(&szReplace, 0, sizeof(szReplace)); | |
// Make Sure Both Chars after Pipe Code are Digits or Numbers. | |
// Else Pass through and Ignore. | |
if ( isdigit(szString[index+1]) && isdigit(szString[index+2]) ) | |
{ | |
switch (szString[index+1]) | |
{ | |
case '0' : // Parse First Digit 0 | |
switch (szString[index+2]) | |
{ | |
// Parse Second Digit 0 - 9 | |
case '0' : | |
ansi_fg(szReplace, 0); | |
break; | |
case '1' : | |
ansi_fg(szReplace, 1); | |
break; | |
case '2' : | |
ansi_fg(szReplace, 2); | |
break; | |
case '3' : | |
ansi_fg(szReplace, 3); | |
break; | |
case '4' : | |
ansi_fg(szReplace, 4); | |
break; | |
case '5' : | |
ansi_fg(szReplace, 5); | |
break; | |
case '6' : | |
ansi_fg(szReplace, 6); | |
break; | |
case '7' : | |
ansi_fg(szReplace, 7); | |
break; | |
case '8' : | |
ansi_fg(szReplace, 8); | |
break; | |
case '9' : | |
ansi_fg(szReplace, 9); | |
break; | |
default : | |
break; | |
} | |
break; | |
case '1' : // Parse First Digit 1 | |
switch (szString[index+1]) | |
{ | |
// Parse Second Digit 10 - 19 | |
case '0' : | |
ansi_fg(szReplace, 10); | |
break; | |
case '1' : | |
ansi_fg(szReplace, 11); | |
break; | |
case '2' : | |
ansi_fg(szReplace, 12); | |
break; | |
case '3' : | |
ansi_fg(szReplace, 13); | |
break; | |
case '4' : | |
ansi_fg(szReplace, 14); | |
break; | |
case '5' : | |
ansi_fg(szReplace, 15); | |
break; | |
case '6' : | |
ansi_bg(szReplace, 16); | |
break; | |
case '7' : | |
ansi_bg(szReplace, 17); | |
break; | |
case '8' : | |
ansi_bg(szReplace, 18); | |
break; | |
case '9' : | |
ansi_bg(szReplace, 19); | |
break; | |
default : | |
break; | |
} | |
break; | |
case '2' : // Parse First Digit 2 | |
switch (szString[index+2]) | |
{ | |
// Parse Second Digit 20 - 23 | |
case '0' : | |
ansi_bg(szReplace, 20); | |
break; | |
case '1' : | |
ansi_bg(szReplace, 21); | |
break; | |
case '2' : | |
ansi_bg(szReplace, 22); | |
break; | |
case '3' : | |
ansi_bg(szReplace, 23); | |
break; | |
default : | |
break; | |
} | |
break; | |
} // End Switch | |
// Check if we matched an Ansi Sequence | |
// If we did, Copy string up to, not including pipe, | |
// Then con cat new ansi sequence to replace pipe in | |
// our new string And copy remainder of string back | |
// to run through Search for next pipe sequence. | |
if (strcmp(szReplace,"") != 0) | |
{ | |
//printf("szReplace found! \r\n"); | |
/* Allocate space szStrBuilder to hold new string */ | |
// String Len of Both Origianl string, And Replacement, plus two | |
// Extra for each '\0' Ending Char in each String. | |
szStrBuilder = (char *) calloc ((size + ( strlen(szReplace) + 2 )), sizeof(char) ); | |
if (szStrBuilder == NULL) | |
{ | |
/* Memory could not be allocated, the program should | |
handle the error here as appropriate. */ | |
return; | |
} | |
// Sequence found. | |
// 1. Copy String up to pipe into new string. | |
for (i = 0; i < index; i++) | |
szStrBuilder[i] = szString[i]; | |
// ConCat New Ansi Sequence into String | |
strcat(szStrBuilder,szReplace); | |
// Skip Past 2 Digits after pipe, and copy over remainder of | |
// String into new string so we have a complete string again. | |
for (i = strlen(szStrBuilder)-1, j = index+3; j < size; i++, j++) | |
szStrBuilder[i] = szString[j]; | |
// Now reaassign new string back to Original String. | |
// Make sure we only copy back the same size of the origianl string | |
// If the string isn't big enough to hold new data, then we will | |
// overwrite memory.. bad! | |
// printf ("%d",sizeof(szString)); | |
// snprintf(szString,sizeof(szString),"%s",szStrBuilder); | |
sprintf(szString,"%s",szStrBuilder); | |
// Now Free szStrBuilder for next Run | |
/* Allocation succeeded. Do something. */ | |
free(szStrBuilder); /* We are done with the String objects, and | |
free the associated memory. */ | |
szStrBuilder = NULL; /* The pointed-to-data must not be used again, | |
unless re-assigned by using calloc | |
again. */ | |
// Reset new size of string since ansi sequence is longer | |
// Then a pipe code. | |
size = strlen(szString); | |
// then test again | |
// if anymore pipe codes exists, if they do repeat process. | |
pch = (char *) memchr (szString, '|', size); | |
if (pch != NULL) | |
{ | |
// Calculate Index Position of | char found in string. | |
index = pch-szString; | |
--index; // Loop will incriment this so we need to set it down 1. | |
//printf("Found second sequence ! index %d, size %d\r\n",index, size); | |
} | |
else | |
{ | |
//printf("Not Found second sequence ! \r\n"); | |
// No Pipe Code in String | |
// no need to test further, so return | |
return; | |
} | |
} | |
} | |
} | |
} // End of For Loop, Finished. | |
} | |
int main(int argc, char *argv[]) | |
{ | |
// Always init Arrays to 0 | |
char tempmem[100] = { 0 }; | |
// Setup String, add 1 bad pipe a| to verify it wil pass through | |
sprintf(tempmem,"Testing a| string |01 woo |04 woo |03 .. |12 .. ."); | |
// Call Function | |
pipe2ansi(tempmem); | |
// Print updated string. | |
printf("\r\n String: %s \r\n", tempmem); | |
system("PAUSE"); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment