Visit Our UNIX and Linux User Community


Using ANSI color codes in gcc compiled program


 
Thread Tools Search this Thread
Top Forums Programming Using ANSI color codes in gcc compiled program
# 1  
Old 04-29-2012
Using ANSI color codes in gcc compiled program

I have put some yellow color codes and works well.

I call the funstion using

Code:
print_usage(stderr, 0);

I would like to know if there is any way, to store the ansi color codes in variables and then call them inside fprintf.
Or have a format followed by the strings I want to output.

Code:
void print_usage(FILE* stream, int exit_code) {

  fprintf (stream,
      "\033[1;33mUSAGE\e[0m\n"
      "   %s options\n\n", program_name);

  fprintf (stream,
    "\033[1;33mACTIONS\e[0m\n"
    "    --cmod=FILE   Velocity model file (required)\n"
    "    --vdx=DV      Interval in x direction in velocity file\n"
    "    --nx=NUM      Interval calculated with vdx = Lx / Nx (default: 20)\n"
    "    --vdz=DV      Interval in z direction in velocity file or\n"
    "    --nz=NUM      Interval calculated with vdz = Lz / Nz (default: 20)\n"
    "    --vdi=DV      Interval along interface\n"
    "    --ni=NUM      Interval calculated with vdi = Li / Ni (default: 20)\n"
    "    --vel=FILE    File with P wave velocity in 'x z v' format\n"
    "    --velp=FILE   File with P wave velocity in 'x z v' format\n"
    "    --vels=FILE   File with S wave velocity in 'x z v' format\n"
    "    --lay=ON/OFF  If --lay=ON, output files are in 'x z v l' format\n"
    "    --intf=       Output file for interfaces in 'x z' format, separated by '>'\n"
    "    -h  --help    Display this usage information\n"
    "    -o  --output=FILE  Write output to file\n"
    "    --vb=LEVEL    Print verbose messages\n"
    "\n");

  exit (exit_code);

}

---------- Post updated at 11:49 PM ---------- Previous update was at 09:56 PM ----------

I have now coded the following which is working well.

How can I simplify this code. For example, it would be good to construct a format, followed by the things I want to print.

Something similar to the following

Code:
frmt_sv = "nRd%snWh=uGn%srcl"
frmt_desc="    %s\n"

fprintf (stream, frmt_sv, "--nx", "NUM");
fprintf (stream, frmt_desc, "interval calculated with vdx = Lx / Nx (default: 20)");

The code is currently as follows

Code:
void print_usage(FILE* stream, int exit_code) {

  const char* progname;
  const char* bYl;
  const char* nRd;
  const char* uGn;
  const char* nWh;
  const char* rcl;
  char* frArgm_sv;

  progname = "getveltest";

  bYl = "\e[1;33m";
  nRd = "\e[0;31m";
  uGn = "\e[4;32m";
  nWh = "\e[0;37m";
  rcl = "\e[0m";

  fprintf (stream,"%s%s%s\n",bYl,"USAGE",rcl);
  fprintf (stream,"    %s%s %s%s%s\n\n",nRd,progname,uGn,"ACTIONS",rcl);

  fprintf (stream,"%s%s%s\n",bYl,"ACTIONS",rcl);
  fprintf (stream,"    %s%s%s%s%s%s%s",nRd,"--cmod",nWh,"=",uGn,"FILE",rcl);
  fprintf (stream,"  %s\n"," sound speed model (mandatory)");

  fprintf (stream,"    %s%s%s%s%s%s%s",nRd,"--vdx",nWh,"=",uGn,"DX",rcl);
  fprintf (stream,"  %s\n","    interval in x direction in velocity file");

  fprintf (stream,"    %s%s%s%s%s%s%s",nRd,"--nx",nWh,"=",uGn,"NUM",rcl);
  fprintf (stream,"  %s\n","    interval calculated with vdx = Lx / Nx (default: 20)");

  fprintf (stream,"    %s%s%s%s%s%s%s",nRd,"--vdz",nWh,"=",uGn,"DZ",rcl);
  fprintf (stream,"  %s\n","    interval in z direction in velocity file");

  fprintf (stream,"    %s%s%s%s%s%s%s",nRd,"--nz",nWh,"=",uGn,"NUM",rcl);
  fprintf (stream,"  %s\n","    interval calculated with vdz = Lz / Nz (default: 20)");

  fprintf (stream,"    %s%s%s%s%s%s%s",nRd,"--vdi",nWh,"=",uGn,"DI",rcl);
  fprintf (stream,"  %s\n","    interval along interface");

  fprintf (stream,"    %s%s%s%s%s%s%s",nRd,"--ni",nWh,"=",uGn,"NUM",rcl);
  fprintf (stream,"  %s\n","    interval calculated with vdi = Li / Ni (default: 20)");

  fprintf (stream,"    %s%s%s%s%s%s%s",nRd,"--vel",nWh,"=",uGn,"FILE",rcl);
  fprintf (stream,"  %s\n","  file with P wave velocity in 'x z v' format");

  fprintf (stream,"    %s%s%s%s%s%s%s",nRd,"--velp",nWh,"=",uGn,"FILE",rcl);
  fprintf (stream,"  %s\n"," file with P wave velocity in 'x z v' format");

  fprintf (stream,"    %s%s%s%s%s%s%s",nRd,"--vels",nWh,"=",uGn,"FILE",rcl);
  fprintf (stream,"  %s\n"," file with S wave velocity in 'x z v' format");

  fprintf (stream,"    %s%s%s%s%s%s%s",nRd,"--lay",nWh,"=",uGn,"ON/OFF",rcl);
  fprintf (stream,"  %s\n","if --lay=ON, output files are in 'x z v l' format");

  fprintf (stream,"    %s%s%s%s%s%s%s",nRd,"--intf",nWh,"=",uGn,"FILE",rcl);
  fprintf (stream,"  %s\n"," output file for interfaces in 'x z' format, separated by '>'");

  fprintf (stream,"    %s%s%s%s%s%s%s",nRd,"--vb",nWh,"=",uGn,"LEVEL",rcl);
  fprintf (stream,"  %s\n","  print verbose messages");

  fprintf (stream,"    %s%s%s%s%s%s%s",nRd,"-u",nWh," ",nRd,"--usage",rcl);
  fprintf (stream,"  %s\n","  displays usage");

  fprintf (stream,"    %s%s%s%s%s%s%s",nRd,"-h",nWh," ",nRd,"--help",rcl);
  fprintf (stream,"  %s\n","   display this usage information");

  exit (exit_code);

}

# 2  
Old 04-29-2012
I wrote some routines for printing ANSI colors inside printf like
Code:
 afprintf(stdout, "This word is ~&110RED~&R!\n");

It's just a translator built on top of standard printf, so should handle any of the usual % sequences. I do not claim that it's ideal or bug-free. Colors cannot be in arguments, only in the command string.

Source code:

Code:
/* ansi.h */
#ifndef __ANSI_H__
#define __ANSI_H__

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

/**
 *      Simple ANSI sequences in C.
 *      example:  aprintf("This word is ~&110RED~&R!\n");
 *
 *      Commands:
 *      ~&R     Reset to defaults
 *      ~&C     Clear screen
 *      ~&111   Sets colors with attr,fg,bg.
 *              attr 0 is normal, attr 1 is bold, others are terminal-dependent.
 *              Colors are
 *              1=red 2=green 4=blue 3=yellow 5=mauve 6=cyan 7=grey/white
 */

int vafprintf(FILE *fp, const char *cmdstr, va_list ap);
int vasprintf(char *buf, const char *cmdstr, va_list ap);
int asprintf(char *buf, const char *cmdstr, ...);
int afprintf(FILE *fp, const char *cmdstr, ...);
int aprintf(const char *cmdstr, ...);
int aprintf(const char *cmdstr, ...);

#endif/*__ANSI_H__*/

Code:
/* ansi.c */

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

#include "ansi.h"

#define ESC     "\x1b["

#if 0
int main(void){ afprintf(stdout, "This word is ~&110RED~&R!\n"); }
#endif

// Convert ~&R into \x1b[0m, etc
static void translate_ansi(char *lcmdstr, const char *cmdstr)
{
        int opos=0;

        while(*cmdstr)
        {
                const char *esc=NULL;
                int a,f,b;

                if(cmdstr[0] == '~')
                if(cmdstr[1] == '&')
                {
                        switch(toupper(cmdstr[2]))
                        {
                        // Can add other single-char sequences here
                        case 'R':       esc=ESC"0m";    break;
                        case 'C':       esc=ESC"2J";    break;
                        default:                        break;
                        }

                        if(esc)
                        {
                                opos+=sprintf(lcmdstr+opos, "%s", esc);
                                cmdstr+=3;
                                continue;
                        }

                        if(sscanf(cmdstr, "~&%01d%01d%01d", &a, &f, &b) == 3)
                        {
                                opos+=sprintf(lcmdstr+opos,
                                        ESC "%d;3%d;4%dm",
                                        a, f%8, b%8);
                                cmdstr += 5;
                                continue;
                        }
                }

                lcmdstr[opos++]=*(cmdstr++);
        }

        lcmdstr[opos]='\0';
}

int vafprintf(FILE *fp, const char *cmdstr, va_list ap)
{
        char lcmdstr[4096];
        translate_ansi(lcmdstr, cmdstr);
        return(vfprintf(fp, lcmdstr, ap));
}


int vasprintf(char *buf, const char *cmdstr, va_list ap)
{
        char lcmdstr[16384];
        translate_ansi(lcmdstr, cmdstr);
        return(vsprintf(buf, lcmdstr, ap));
}

int asprintf(char *buf, const char *cmdstr, ...)
{
        int ret;
        va_list ap;
        va_start(ap, cmdstr);
                ret=vasprintf(buf, cmdstr, ap);
        va_end(ap);

        return(ret);
}

int afprintf(FILE *fp, const char *cmdstr, ...)
{
        char buf[16384];
        int ret;
        va_list ap;

        va_start(ap, cmdstr);
                ret=vafprintf(fp, cmdstr, ap);
        va_end(ap);

        return(ret);
}

int aprintf(const char *cmdstr, ...)
{
        int ret;
        va_list ap;

        va_start(ap, cmdstr);
                ret=vafprintf(stdout, cmdstr, ap);
        va_end(ap);

        return(ret);
}

This User Gave Thanks to Corona688 For This Post:
# 3  
Old 04-29-2012
I had coded the following using the letters s, v and d.

s stands for string argument
v stands for value
d stands for description

If I have a number NUM in front of the letter, it means that there are NUM arguments of that type.

Example
Code:
prUsge4_sv ( stdout, "--cmod", "FILE" );

The 4 means a shift to the right by four characters

prints
Code:
    --cmod=FILE

Another example

Code:
prUsge4_2sv ( stdout, "--bracd", "--mindacc", "DIST" );

gives

Code:
    --bracd, --mindacc=DIST

I would like to use the following function calls, but try to have the colors in each function more managable using
a method where I can declare what color I want to use when calling fprintf. Or something similar to what you have done.

The code is as follows:

Code:
#ifndef clorfncs_hh
#define clorfncs_hh

#include <stdlib.h>

void prNwln (
  FILE*  stream ) {

  fprintf ( stream, "\n", "" );

}

void prTitl (
  FILE*  stream,
  const char*  titl ) {

  const char* frTitl;
  frTitl = "\e[1;33m%s\e[0m\n";
  fprintf ( stream, frTitl, titl );

}

void prTitl4 (
  FILE*  stream,
  const char*  titl ) {

  const char* frTitl;
  frTitl = "\e[1;33m%s\e[0m\n";
  fprintf ( stream, frTitl, titl );

}

void prUsge_sv (
  FILE*  stream,
  const char*  prog,
  const char*  value ) {

  const char* frUsge_sv;
  frUsge_sv = "\e[0;31m%s\e[0m \e[4;32m%s\e[0m\n";
  fprintf ( stream, frUsge_sv, prog, value );

}

void prUsge4_sv (
  FILE*  stream,
  const char*  prog,
  const char*  value ) {

  const char* frUsge4_sv;
  frUsge4_sv = "    \e[0;31m%s\e[0m \e[4;32m%s\e[0m\n";
  fprintf ( stream, frUsge4_sv, prog, value );

}

void prUsge_s2v (
  FILE*  stream,
  const char*  prog,
  const char*  value1,
  const char*  value2 ) {

  const char* frUsge_s2v;
  frUsge_s2v = "\e[0;31m%s\e[0m \e[4;32m%s\e[0m \e[4;32m%s\e[0m\n";
  fprintf ( stream, frUsge_s2v, prog, value1, value2 );

}

void prUsge4_s2v (
  FILE*  stream,
  const char*  prog,
  const char*  value1,
  const char*  value2 ) {

  const char* frUsge4_s2v;
  frUsge4_s2v = "    \e[0;31m%s\e[0m \e[4;32m%s\e[0m \e[4;32m%s\e[0m\n";
  fprintf ( stream, frUsge4_s2v, prog, value1, value2 );

}

void prArgm_sv (
  FILE*  stream,
  const char*  actn,
  const char*  value ) {

  const char* frArgm_sv;
  frArgm_sv = "\e[0;31m%s\e[0m\e[0;37m=\e[4;32m%s\e[0m\n";
  fprintf ( stream, frArgm_sv, actn, value );

}

void prArgm4_sv (
  FILE*  stream,
  const char*  actn,
  const char*  value ) {

  const char* frArgm4_sv;
  frArgm4_sv = "    \e[0;31m%s\e[0m\e[0;37m=\e[4;32m%s\e[0m\n";
  fprintf ( stream, frArgm4_sv, actn, value );

}

void prArgm_2s (
  FILE*  stream,
  const char*  actn1,
  const char*  actn2 ) {

  const char* frArgm_2s;
  frArgm_2s = "\e[0;31m%s\e[0;37m, \e[0;31m%s\e[0m\n";
  fprintf ( stream, frArgm_2s, actn1, actn2 );

}

void prArgm4_2s (
  FILE*  stream,
  const char*  actn1,
  const char*  actn2 ) {

  const char* frArgm4_2s;
  frArgm4_2s = "    \e[0;31m%s\e[0;37m, \e[0;31m%s\e[0m\n";
  fprintf ( stream, frArgm4_2s, actn1, actn2 );

}

void prArgm_2sd (
  FILE*  stream,
  const char*  actn1,
  const char*  actn2,
  const char*  desc ) {

  const char* frArgm_2sd;
  frArgm_2sd = "\e[0;31m%s\e[0;37m, \e[0;31m%s\e[0m  \e[0;37m%s\e[0m\n";
  fprintf ( stream, frArgm_2sd, actn1, actn2, desc );

}

void prArgm4_2sd (
  FILE*  stream,
  const char*  actn1,
  const char*  actn2,
  const char*  desc ) {

  const char* frArgm4_2sd;
  frArgm4_2sd = "    \e[0;31m%s\e[0;37m, \e[0;31m%s\e[0m  \e[0;37m%s\e[0m\n";
  fprintf ( stream, frArgm4_2sd, actn1, actn2, desc );

}

void prArgm_svd (
  FILE*  stream,
  const char*  actn,
  const char*  value,
  const char*  desc ) {

  const char* frArgm_svd;
  frArgm_svd = "\e[0;31m%s\e[0m\e[0;37m=\e[4;32m%s\e[0m  \e[0;37m%s\e[0m\n";
  fprintf ( stream, frArgm_svd, actn, value, desc );

}

void prArgm4_svd (
  FILE*  stream,
  const char*  actn,
  const char*  value,
  const char*  desc ) {

  const char* frArgm4_svd;
  frArgm4_svd = "    \e[0;31m%s\e[0m\e[0;37m=\e[4;32m%s\e[0m  \e[0;37m%s\e[0m\n";
  fprintf ( stream, frArgm4_svd, actn, value, desc );

}

void prArgm8_svd (
  FILE*  stream,
  const char*  actn,
  const char*  value,
  const char*  desc ) {

  const char* frArgm8_svd;
  frArgm8_svd = "        \e[0;31m%s\e[0m\e[0;37m=\e[4;32m%s\e[0m  \e[0;37m%s\e[0m\n";
  fprintf ( stream, frArgm8_svd, actn, value, desc );

}

void prDesc (
  FILE*  stream,
  const char*  desc ) {

  const char* frDesc;
  frDesc = "\e[0;37m%s\e[0m\n";
  fprintf ( stream, frDesc, desc );

}

void prDesc4 (
  FILE*  stream,
  const char*  desc ) {

  const char* frDesc4;
  frDesc4 = "    \e[0;37m%s\e[0m\n";
  fprintf ( stream, frDesc4, desc );

}

void prUsgeMscl (
  FILE*  stream ) {

  const char* desc;

  prNwln ( stream );
  prTitl ( stream, "MISCELLANEOUS" );

  desc="print verbose messages";
  prArgm8_svd ( stream, "--vb", "LEVEL", desc );

  desc="   displays usage";
  prArgm4_2sd ( stream, "-u", "--usage", desc );

  desc="   prints some examples using getveltest";
  prArgm4_2sd ( stream, "-e", "--examples", desc );

  desc="    display this usage information";
  prArgm4_2sd ( stream, "-h", "--help", desc );

}

#endif

Do you think I should not use something like

Code:
void prDesc4 (
  FILE*  stream,
  const char*  desc ) {

  const char* frDesc4;
  frDesc4 = "    \e[0;37m%s\e[0m\n";
  fprintf ( stream, frDesc4, desc );

}


Last edited by kristinu; 04-29-2012 at 05:31 PM..
# 4  
Old 04-30-2012
I really don't know what you want anymore. You don't want to pass them into the function because it becomes so many arguments, but you don't want to embed them in the printf command string either. One way or another, you need to tell it which parts you want to be what color and intensity.

I'd just use the aprintf I gave you instead of making 20 very slightly-different printing functions:

Code:
afprintf(stdout, "~&110--bracd~&R, ~&110--mindacc~&R=~&120DIST~&R\n");
// Or perhaps
afprintf(stdout, "~&110%s~&R, ~&110--mindacc~&R=~&120%s~&R\n", "--bradc", "DIST");

You could make macros for various colors, since you can stick strings together like

Code:
#define RED "~&110"
#define RESET "~&R"

afprintf(stdout, "This word is " RED "red!" RESET "\n");

Short of building an HTML parser in your code so you can do [RED]stuff[/RED] I don't know how to make it more convenient for you.

Last edited by Corona688; 04-30-2012 at 01:07 PM..
# 5  
Old 04-30-2012
I agree with you. Instead of calling fprintf, I will call your routines inside the functions I have created. Took me some time to decide how to approach things. I do like your method.

---------- Post updated at 11:11 AM ---------- Previous update was at 11:05 AM ----------

Quote:
Originally Posted by Corona688
I really don't know what you want anymore. You don't want to pass them into the function because it becomes so many arguments, but you don't want to embed them in the printf command string either. One way or another, you need to tell it which parts you want to be what color and intensity.

I'd just use the aprintf I gave you instead of making 20 very slightly-different printing functions:

Code:
afprintf(stdout, "~&110--bracd~&R, ~&110--mindacc~&R=~&120DIST~&R\n");
// Or perhaps
afprintf(stdout, "~&110%s~&R, ~&110--mindacc~&R=~&120%s~&R\n", "--bradc", "DIST");

You could make macros for various colors, since you can stick strings together like

Code:
#define RED "~&110"
#define RESET "~&R"

afprintf(stdout, "This word is " RED "red!" RESET "\n");

Short of building an HTML parser in your code so you can do [RED]stuff[/RED] I don't know how to make it more convenient for you.
I wrote the different functions so that they take some standard color sequence instead of specifying the color everytime. Internally I will set the color sequence and then call your function to print the actual colored output.
# 6  
Old 04-30-2012
That's the kind of thing I'd make macros for. It helps you can stack strings like "This" "is" "a" "string" and the compiler will put it together like "Thisisastring", you can assemble your command string out of string literals passed into a macro.

Code:
#define RESET "~&R"
#define COLORWORD(COLOR, STRING) afprintf(stdout, "This word is " COLOR "%s!" RESET "\n", STRING)

// Note the "~&110" here must be a literal "string" in double quotes, and never a pointer or var.
// "red", etc on the other hand can be whatever you want.
COLORWORD("~&110", "red");
COLORWORD("~&120", "green");
COLORWORD("~&140", "blue");


Last edited by Corona688; 04-30-2012 at 01:30 PM..

Previous Thread | Next Thread
Test Your Knowledge in Computers #38
Difficulty: Easy
The standard port number for SMTP applications is 25.
True or False?

10 More Discussions You Might Find Interesting

1. Programming

Local variable in a C function is not getting created in stack when its compiled with GCC

Hi, I am working in UEFI EDK2 Bios source. We created a platform related new package in the EDK2 source. I find a strange issue with the platform related code we added. When I did source level debugging I noticed the local variable in a C function is not getting created in stack when its... (6 Replies)
Discussion started by: Divya R
6 Replies

2. Shell Programming and Scripting

Help with awk color codes based on condition

HI i have two files say test and test1 Test.txt Code: Lun01 2TB 1.99TB 99.6% Lun02 2TB 1.99TB 99.5% Lun03 2TB 1.99TB 99.5% Lun04 2TB 1.55TB 89.6% Code: Test1.txt Lun01 2TB 1.99TB 89.5% Lun02 2TB 1.99TB 99.5% Lun03 2TB 1.99TB 99.5% Requirement is to compare... (6 Replies)
Discussion started by: venkitesh
6 Replies

3. Solaris

Newly Compiled GCC 4.4.4 on Solaris sparc gives problem with -m32/-m64 flags

Hello experts, This issue has kept me busy all day long. It started off with openssl compilation which was giving linking error with following message: /usr/local/bin/ld: target elf32-sparc not found collect2: ld returned 1 exit status I tried every step possible thing that I could think... (2 Replies)
Discussion started by: d_shanke
2 Replies

4. UNIX for Dummies Questions & Answers

Display file with escaped color codes

Hi, I have a file containing color codes: Fri May 25 17:13:04 2012: Starting MTA: exim4^ Loading cpufreq kernel modules...^How can I display it colorized on a linux terminal? (4 Replies)
Discussion started by: ripat
4 Replies

5. Shell Programming and Scripting

zsh, prompt, variable expansion, ANSI color sequences

Hi! I am using latest ZSH and I have setopt prompt_subst I have a global hash array variable which contains some color definitions with color names as keys and 256-color ANSI codes (with %{ and %}) as values, eg %{\ePS1="$FG Hello World (%M) > " or PS1=$'$FG Hello World (%M) > ' then it... (3 Replies)
Discussion started by: galanom
3 Replies

6. Homework & Coursework Questions

Calling compiled C program with Perl program

Long story short: I'm working inside of a Unix SSH under a bash shell. I have to code a C program that generates a random number. Then I have to call the compiled C program with a Perl program to run the C program 20 times and put all the generated random #s into a text file, then print that text... (1 Reply)
Discussion started by: jdkirby
1 Replies

7. Programming

pthread_mutex_lock in ANSI C vs using Atomic builtins of GCC

I have a program which has 7-8 threads, and lots of shared variables; these variables (and also they may not the primitive type, they may be enum or struct ), then they may read/write by different threads at the same time. Now, my design is like this, typedef unsigned short int UINT16;... (14 Replies)
Discussion started by: sehang
14 Replies

8. UNIX for Dummies Questions & Answers

Regular expression on hex color codes

I want to have all hex color codes in a given stylesheet in uppercase, so #fff should be converted to #FFF for instance. Here is the regular expression I use to match and convert hex color codes to uppercase: sed -e 's/^#({3}$)|({6}$)/^#({3}$)|({6}$)/' main.css However, no conversion to uppercase... (6 Replies)
Discussion started by: figaro
6 Replies

9. UNIX for Dummies Questions & Answers

Using color escape codes in less

Hi all, Not sure how "for dummies" this question is, but I'd better use understatement... A. My Environment ============== I am using RedHat Linux, version 2.6.18-53.el5. When I type less --version I get: less 394 Copyright (C) 1984-2005 Mark Nudelman ... My terminal is configured... (1 Reply)
Discussion started by: Source2Exe
1 Replies

10. Linux

gcc compiled executable not working across x86_64 linux platforms

Hi I compiled a hello world program on two different 64-bit Linux machines, named quimby and node0331. When I compile on quimby and run on node0331 I get a "Floating exception (core dumped)" error. But if I do it in reverse, things work fine. Here's my compilation on quimby: $ uname -a... (3 Replies)
Discussion started by: same1290
3 Replies

Featured Tech Videos