Miscellaneous C functions and source code

By Frank Cox
(December 12, 2009)

Most of these functions consist of self-contained “demo programs” that can be compiled as-is for testing, then you can rip out any parts that you want to use in own programs.

These programs were written on Centos 5 and most require ncurses, which is installed by default on most Linux distributions. You should be able to compile them as-is on pretty much any modern Linux or Unix system. I really don't know what it would take to get this stuff working on Microsoft Windows, though there does appear to be a MS Windows compatible version of ncurses called pdcurses which might work.

All programs on this web page are subject to the following copyright notice:

Copyright (c) 2009, Frank Cox
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY FRANK COX ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL FRANK COX BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.

PERCENT BAR

A moving progress bar that can be used to count up or down while doing things like reading datafiles so the program user can see that something is happening.

This function is based on a subroutine written by James Goldbloom in 1996. You can download the original here.


#include <ncurses.h>
#include <string.h>
#include <stdbool.h>
void percentbar(const int value, const int high, const int y, const int x, int width, const int fg, const int bg, const int highlight, const bool showvalues);
int main(void)
{
        initscr();
        start_color();
        percentbar(50,100,21,0,73,11,6,15,true);
        getch();
        endwin();
        return 0;
}
void percentbar(const int value, const int high, const int y, const int x, int width, const int fg, const int bg, const int highlight, const bool showvalues)
        //Example:   percentbar(50,100,21,0,73,11,6,15,true); <-- Display a 50% bar at bottom of screen
{
int oldx, oldy, percentage,counter;
attr_t attributes; // ncurses text attributes
short cpair;       // ncurses color pair (not using this one at the moment)
char tempbar[20];
getyx(stdscr,oldy,oldx);
attr_get(&attributes,&cpair,NULL); //get current text attributes before we start
if (width > 73)
        width = 73;
percentage = value*100/high;
if (fg < 8)
        {
                init_pair(63,fg,bg);
                attrset(COLOR_PAIR(63));
        }
        else
        {
                init_pair(63,fg-8,bg);
                attrset(COLOR_PAIR(63)|A_BOLD);
        }
move(y,x);
attron(A_ALTCHARSET);
if (showvalues)
        {
        sprintf(tempbar,"%d/%d",value,high);
        addch(ACS_ULCORNER);
        for (counter=1; counter < width/2; counter++)
                addch(ACS_HLINE);
        addch(ACS_RTEE);
        attroff(A_ALTCHARSET);
        if (highlight < 8)
        {
                init_pair(62,highlight,bg);
                attrset(COLOR_PAIR(62));
        }
        else
        {
                init_pair(62,highlight-8,bg);
                attrset(COLOR_PAIR(62)|A_BOLD);
        }
        addstr(tempbar);
        if (fg < 8)
                attrset(COLOR_PAIR(63));
        else
                attrset(COLOR_PAIR(63)|A_BOLD);
        attron(A_ALTCHARSET);
        addch(ACS_LTEE);
        for (counter=0; counter < width-(width/2+strlen(tempbar))+4; counter++)
                addch(ACS_HLINE);
        addch(ACS_URCORNER);
        }
else
        {
        addch(ACS_ULCORNER);
        for (counter=-5; counter < width; counter++ )
                addch(ACS_HLINE);
        addch(ACS_URCORNER);
        }
move(y+1,x);
addch(ACS_VLINE);
attroff(A_ALTCHARSET);
if (highlight < 8)
        attrset(COLOR_PAIR(62));
else
        attrset(COLOR_PAIR(62)|A_BOLD);
printw("%d%%",percentage);
sprintf(tempbar,"%d",percentage);
for (counter=1; counter < 5-strlen(tempbar); counter++)
        addch(' ');
move(y+1,x+6);
if (fg < 8)
        attrset(COLOR_PAIR(63));
else
        attrset(COLOR_PAIR(63)|A_BOLD);
for (counter=0; counter < width*percentage/100; counter++)
        addch(ACS_DIAMOND);
if (width-width*percentage/100 != 1)
        {
        attron(A_ALTCHARSET);
        for (counter=0; counter < width-width*percentage/100; counter++)
                addch(ACS_BULLET);
        addch(ACS_VLINE);
        }
move(y+2,x);
addch(ACS_LLCORNER);
for (counter=-5; counter < width; counter++)
        addch(ACS_HLINE);
addch(ACS_LRCORNER);
attroff(A_ALTCHARSET);
attrset(attributes); //restore text attributes attributes
move(oldx,oldy); // restore cursor location
}

POSIX FILE LOCKING FUNCTIONS

A function to open and close a file using POSIX file locking.


#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
FILE* openfile(const char *filename, const char *operation);
void closefile(FILE*);
int main(void)
{
        FILE *fp;
        char name[20];
        fp=openfile("text.txt","a");
        printf("Hit a key to continue\n");
        scanf("%s", name);
        closefile(fp);
        return 0;
}
FILE* openfile(const char *filename, const char *operation) 
{
        struct flock fl;
        FILE *file;
        if (strcmp(operation,"r") == 0)
                        fl.l_type   = F_RDLCK;  /* F_RDLCK, F_WRLCK, F_UNLCK    */
        else
                        fl.l_type   = F_WRLCK;
        fl.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */
        fl.l_start  = 0;        /* Offset from l_whence         */
        fl.l_len    = 0;        /* length, 0 = to EOF           */
        fl.l_pid    = getpid(); /* our PID                      */
        if ((file = fopen(filename,operation)) == NULL)
                {                      
                printf(" can't open %s\n", filename);
                exit(1);
                }
        if (fcntl(fileno(file), F_SETLKW, &fl) == -1)
                {
                printf("can't set lock %s\n",filename);
                exit(1);
                }
        return file;
}
void closefile(FILE *file)
{
        struct flock fl;
        fl.l_type   = F_UNLCK;  /* F_RDLCK, F_WRLCK, F_UNLCK    */
        fl.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */
        fl.l_start  = 0;        /* Offset from l_whence         */
        fl.l_len    = 0;        /* length, 0 = to EOF           */
        fl.l_pid    = getpid(); /* our PID                      */
        fflush(file); // flush data before releasing lock
        if (fcntl(fileno(file), F_SETLK, &fl) == -1) {
                printf("can't release file lock.\n");
                exit(1);
        }
        fclose(file);
        return;
}


TEXT EDITOR

A simple multi-line text editor. As presented here, this text editor converts the return key to a space, you must hit tab to exit the function, and the editor will reject the < and > keys. It would be simple to change this behaviour to translate or reject any keys that you wish and to exit the function with any key you choose.


#include <ncurses.h>
#include <string.h>
#include <stdbool.h>
//string length for word wrap in ad text editor
#define WORDWRAPLENGTH 76
bool texteditor(char *text);
void left(char *string, const int length);
void right(char *string, const int length);
int main(void)
        {
        initscr();
        noecho();
        cbreak();
        keypad(stdscr,TRUE);
        start_color();
        char adtext[256]="\0";
        if (texteditor(adtext))
                ;
        else
                strcpy(adtext,"Esc hit");
        clear();
        addstr(adtext);
        getch();
        endwin();
        return(0);
        }
bool texteditor(char *text)
        {
        int counter, counter2, ky=0;
        int csrpos=0;
        char temp[256];
        char wrappedtext[4][WORDWRAPLENGTH+1];
        bool ins=false;
        for (counter=strlen(text); counter < 256; counter++)
                text[counter]='\0';
        while (ky != 9) // repeat until we hit the tab key
                {
                for (counter=0; counter < 4; counter++)
                        wrappedtext[counter][0] = '\0';
                for (counter=0; counter < 4; counter++)
                        {
                        strcpy(temp,text);
                        right(temp,strlen(temp)-strlen(wrappedtext[0])-strlen(wrappedtext[1])-strlen(wrappedtext[2])-counter);
                        if (temp[0] =='\0')
                                break;
                        left(temp,WORDWRAPLENGTH);
                        if (strchr(temp,' ') == NULL || strlen(temp) < WORDWRAPLENGTH)
                                {
                                strcpy(wrappedtext[counter],temp);
                                break;
                                }
                        else
                                {
                                left(temp,strrchr(temp,' ')-temp);
                                strcpy(wrappedtext[counter],temp);
                                }
                        }
                for (counter=0; counter < 4; counter++)
                        {
                        move(counter+4,1);
                        for (counter2=0; counter2 < 76; counter2++)
                                addch(' ');
                        mvaddstr(counter+4,1,wrappedtext[counter]);
                        }
                // put the cursor on the screen
                if (strlen(text) > 0)
                        {
                        if (csrpos < strlen(wrappedtext[0])+2)
                                move(4,csrpos+1);
                        else if (csrpos < strlen(wrappedtext[0])+strlen(wrappedtext[1])+3)
                                move(5,csrpos-strlen(wrappedtext[0]));
                        else if (csrpos < strlen(wrappedtext[0])+strlen(wrappedtext[1])+strlen(wrappedtext[2])+4)
                                move(6,csrpos-strlen(wrappedtext[0])-strlen(wrappedtext[1])-1);
                        else
                                move(7,csrpos-1-strlen(wrappedtext[0])-strlen(wrappedtext[1])-strlen(wrappedtext[2])-1);
                        }
                else
                        move(4,1);
                refresh();
                ky=getch();
                switch (ky)
                        {
                        case KEY_HOME:
                                csrpos =0;
                                break;
                        case KEY_UP:
                                if (csrpos < strlen(wrappedtext[0])+2)
                                        ; // do nothing
                                else if (csrpos < strlen(wrappedtext[0])+strlen(wrappedtext[1])+3)
                                        csrpos=csrpos-strlen(wrappedtext[0])-1;
                                else if (csrpos < strlen(wrappedtext[0])+strlen(wrappedtext[1])+strlen(wrappedtext[2])+4)
                                        csrpos=csrpos-strlen(wrappedtext[1])-1;
                                else
                                        csrpos=csrpos-strlen(wrappedtext[2])-1;
                                break;
                        case KEY_LEFT:
                                if (csrpos > 0)
                                        csrpos--;
                                break;
                        case KEY_RIGHT:
                                if (csrpos <= strlen(text))
                                        csrpos++;
                                break;
                        case KEY_END:
                                csrpos=strlen(text);
                                break;
                        case KEY_DOWN:
                                if (csrpos< strlen(wrappedtext[0]) +2) 
                                        {
                                        if (csrpos + strlen(wrappedtext[0]) < strlen(text))
                                                csrpos=csrpos + strlen(wrappedtext[0])+1;
                                        }
                                else if (csrpos< strlen(wrappedtext[0])+strlen(wrappedtext[1]) +3) 
                                        {
                                        if (csrpos + strlen(wrappedtext[1]) < strlen(text))
                                                csrpos= csrpos+ strlen(wrappedtext[1])+1;
                                        }
                                else if (csrpos < strlen(wrappedtext[0])+strlen(wrappedtext[1]) + strlen(wrappedtext[2]) +4)  
                                        {
                                        if (csrpos + strlen(wrappedtext[2]) < strlen(text))
                                                        csrpos=csrpos+strlen(wrappedtext[2])+1;
                                        else
                                                        csrpos=strlen(text)+1;
                                        }
                                break;
                        case KEY_IC: //insert key
                                ins = !ins;
                                if (ins)
                                        {
                                        mvaddstr(15,1,"ins");
                                        curs_set(2);
                                        }
                                else
                                        {
                                        mvaddstr(15,1,"   ");
                                        curs_set(1);
                                        }
                                break;
                        case KEY_DC: //delete key
                                if (csrpos > strlen(text)-1)
                                        break;
                                for (counter=csrpos+1;text[counter] != '\0'; counter++)
                                        text[counter-1]=text[counter];
                                text[counter-1]='\0';
                                break;
                        case 9: // tab
                                //if the entry variable is 9 (tab) we can exit this function
                                break;
                        case KEY_BACKSPACE:
                                if (csrpos > 0)
                                        {
                                        for (counter=csrpos; text[counter] != '\0'; counter++)
                                                text[counter-1]=text[counter];
                                        text[counter-1]='\0';
                                        csrpos--;
                                        }
                                break;
                        case '<': // don't accept <> in the editor
                        case '>':
                                break;
                        case 27: //esc
                                // esc twice to get out, otherwise eat the chars that don't work
                                //from home or end on the keypad
                                ky=getch();
                                if (ky == 27)
                                        return (false);
                                else
                                        if (ky=='[')
                                                {
                                                getch();
                                                getch();
                                                }
                                        else 
                                                ungetch(ky);
                                break;
                        default:
                                if (ky ==10)
                                        ky = ' ';
 //convert return to a space
                                if (ky > 31 && ky < 126 && strlen(text) < 255 && strlen(wrappedtext[3]) < WORDWRAPLENGTH)
                                        {
                                        if (ins)
                                                memmove(text+csrpos+1,text+csrpos,255-csrpos);
                                        text[csrpos]=ky;
                                        if (csrpos < 255)
                                                ++csrpos;
                                        }
                        }
                }
        return(true);
        }
void left(char *string, const int length)
        {
        if (strlen(string) > length)
                string[length]='\0';
        return;
        }
void right(char *string, const int length)
        {
        if (strlen(string) > length)
                memmove(string, string+strlen(string)-length,length+1);
        return;
        }


EDITABLE SINGLE-LINE INPUT FIELD

You can specify what characters are allowed in the field. The function returns a value which is dependent on how the function was exited.

This function is based on a subroutine written by David Zarnitzky in 1992. You can download the original here.


#include <ncurses.h>
#include <string.h>
#include <stdbool.h>
#define MAXIMUMUPUTSTRINGLENGTH 80
int uput(const int y,const int x,const int length,const int fg,const int bg,char *whole,bool ins,const char *permitted);
char* rtrim(char* string, char junk);
void insert(char *, const char*, const int);
int main(void)
{
        char whole[MAXIMUMUPUTSTRINGLENGTH];
        int returnvalue;
        initscr();
        cbreak();
        noecho();
        keypad(stdscr,TRUE);
        start_color();
        move(7,6);
        addstr("1234567890");
        refresh();
        strcpy(whole,"abcd");
        returnvalue=uput(6,6,6,0,7,whole,false,"123456789/*-+=()");
        move(20,30);
        printw("returnvalue=%d whole=%s\n",returnvalue,whole);
        refresh();
        flushinp();
        getch();
        endwin();
        return 0;
}
int uput(const int y,const int x,const int length,const int fg,const int bg,char *whole,bool ins,const char *permitted)
{
/*
+------------------------[ WHAT YOU PUT IN ]-------------------------------+
|UPUT(y, x, length, fg, bg, whole, ins, permitted)                        |
+--------------------------------------------------------------------------+
|y -> Row where INPUT will start                                           |
|x -> Column where INPUT will start                                        |
|length -> Maximum length of INPUT                                         |
|fg -> Foreground color of INPUT line                                      |
|bg -> Background color of INPUT line                                      |
|whole -> String to be edited                                              |
|ins -> TRUE or FALSE for INSERT on/off                                    |
| permitted$ = the only valid characters                                   |
+---------------------[ WHAT YOU GET BACK ]--------------------------------+
|                                                                          |
| If UPUT is exited by the user pressing ESCAPE, then the FUNCTION will    |
| return the original string it was given (ie: no changes are made).  If   |
| UPUT is exited any other way (TAB, SHIFT-TAB, UP, DOWN, ENTER), then     |
| the edited string is returned.                                           |
|                                                                          |
| In either case, the SHARED variable "keyflag%" is returned with a value  |
| which is dependent on HOW UPUT was exited, following the chart below     |
|                                      +-----------------------------------+
| ESCAPE     -> keyflag = 5            |The values are based on the KEYPAD!|
| ENTER      -> keyflag = 0            +--------------+--------+-----------+
| UP ARROW   -> keyflag = 8            |       (7)    | UP(8)  | (9)       |
| DOWN ARROW -> keyflag = 2            +--------------+--------+-----------+
| TAB        -> keyflag = 6            |   SHFT-TAB(4)| ESC(5) |TAB(6)     |
| SHIFT-TAB  -> keyflag = 4            +--------------+--------+-----------+
|                                      |       (1)    | DOWN(2)|  (3)      |
|                                      +--------------+--------+-----------|
|                                      |    ENTER(0)  |                    |
+--------------------------------------+-----------------------------------+
Requires rtrim() and insert() functions
--------------
NCURSES BASIC COLORS
--------------
0 Black   COLOR_BLACK (DOS Color #0)
1 Red     COLOR_RED (DOS Color #4)
2 Green   COLOR_GREEN (DOS Color #2)
3 Brown   COLOR_YELLOW (DOS Color #6)
4 Blue    COLOR_BLUE (DOS Color #1)
5 Magenta COLOR_MAGENTA (DOS Color #5)
6 Cyan    COLOR_CYAN (DOS Color #3)
7 White   COLOR_WHITE (DOS Color #7)
------------------------------------------------
COLORS WITH BOLD ATTRIBUTE SET (Foreground only)
------------------------------------------------
0 Gray (DOS Color #8)
1 Light Red (DOS Color #12)
2 Light Green (DOS Color #10)
3 Yellow (DOS Color #14)
4 Light Blue (DOS Color #9)
5 Light Magenta (DOS Color #13)
6 Light Cyan (DOS Color #11)
7 High Intensity White (DOS Color #15)
*/
        int flag = 0, curspos=0,counter, ky;
        char tempwhole[MAXIMUMUPUTSTRINGLENGTH];
        char kystring[2];
        bool exitflag=false;
        kystring[1]='\0';
        strcpy(tempwhole,whole);
        if (fg < 8)
        {
                init_pair(64,fg,bg);
                attrset(COLOR_PAIR(64));
        }
        else
        {
                init_pair(64,fg-8,bg);
                attrset(COLOR_PAIR(64)|A_BOLD);
        }
        do
        {
                move(y,x);
                for (counter=0; counter < length; counter++)
                        addch(' ');
                move (y,x);
                addstr(whole);
                move(y,x+curspos);
                if (ins)
                        curs_set(2);
                else
                        curs_set(1);
                refresh();
                ky=getch();
                switch (ky)
                {
                        case KEY_LEFT:
                                if (curspos != 0)
                                        curspos--;
                                break;
                        case KEY_RIGHT:
                                if (curspos != length-1 && whole[curspos] != '\0')
                                        curspos++;
                                break;
                        case KEY_HOME:
                        //case KEY_A1: =KEY_HOME on Linux so not required 
                                curspos = 0;
                                break;
                        case KEY_END:
                        //case KEY_C1: =KEY_END on Linux so not required
                                rtrim(whole,' ');
                                curspos=strlen(whole);
                                if (strlen(whole) == length)
                                        curspos--;
                                break;
                        case KEY_IC: //insert key
                                ins = !ins;
                                if (ins)
                                        curs_set(2);
                                else
                                        curs_set(1);
                                break;
                        case KEY_DC: //delete key
                                if (curspos > strlen(whole)-1)
                                        break;
                                for (counter=curspos+1;whole[counter] != '\0'; counter++)
                                        whole[counter-1]=whole[counter];
                                whole[counter-1]='\0';
                                break;
                        case KEY_BACKSPACE:
                                if (curspos > 0)
                                        {
                                        for (counter=curspos; whole[counter] != '\0'; counter++)
                                                whole[counter-1]=whole[counter];
                                        whole[counter-1]='\0';
                                        curspos--;
                                        }
                                break;
                        case 10: // enter
                                flag=0;
                                exitflag=true;
                                break;
                        case KEY_UP: // up-arrow
                                flag=8;
                                exitflag=true;
                                break;
                        case KEY_DOWN: // down-arrow
                                flag=2;
                                exitflag=true;
                                break;
                        case 9: // tab
                                flag=6;
                                exitflag=true;
                                break;
                        case KEY_BTAB: // shift-tab
                                flag=4;
                                exitflag=true;
                                break;
                        case 27: //esc
                                // esc twice to get out, otherwise eat the chars that don't work
                                //from home or end on the keypad
                                ky=getch();
                                if (ky == 27)
                                        {
                                        strcpy(whole,tempwhole);
                                        flag=5;
                                        exitflag=true;
                                        }
                                else
                                        if (ky=='[')
                                                {
                                                getch();
                                                getch();
                                                }
                                        else 
                                                ungetch(ky);
                                break;
                        default:
                                if (strchr(permitted,ky))
                                {
                                kystring[0]=ky;
                                        if (ins)
                                                {
                                                if (curspos < strlen(whole))
                                                        {
                                                        if (strlen(whole) < length)
                                                                insert(whole,kystring,curspos);
                                                        else
                                                                curspos--;
                                                        }
                                                else
                                                        strcat(whole,kystring);
                                                }
                                        else
                                                if (curspos < strlen(whole)) 
                                                        whole[curspos]=ky;
                                                else
                                                        strcat(whole,kystring);
                                if (curspos < length-1)
                                        ++curspos;
                                }
                }
        } while (!exitflag);
        rtrim(whole,' ');
        return (flag);
}
char* rtrim(char* string, char junk)
{
    char* original = string + strlen(string);
    while(*--original == junk);
    *(original + 1) = '\0';
    return string;
}
void insert(char *st, const char *s2, const int location)
{
        char temp[MAXIMUMUPUTSTRINGLENGTH];
        int counter, tempstringlength;
        strncpy(temp,st,location);
        temp[location]='\0';
        strcat(temp,s2);
        tempstringlength=strlen(temp);
        for (counter=location; st[counter] != '\0' && counter < MAXIMUMUPUTSTRINGLENGTH; counter++, tempstringlength++)
                temp[tempstringlength]=st[counter];
        temp[tempstringlength]='\0';
        strcpy(st,temp);
        return;
}


DOS COLOR FUNCTION

A simple function to assign colors to text based on the MS-DOS color numbers. This function puts all text on a cyan background; you can change it to any background color that you require.


void start_dos_colors(void)
        {
        init_pair(1,0,6); // black
        init_pair(2,3,6); // blue
        init_pair(3,2,6); // green
        init_pair(4,1,6); // red
        init_pair(5,5,6); // magenta
        init_pair(6,3,6); // brown
        init_pair(7,7,6); // white
        return;
        }
void doscolor(const int color)
        {
        switch (color)
                {
                case 0:
                        attrset(COLOR_PAIR(1)); //black
                        break;
                case 1:
                        attrset(COLOR_PAIR(2)); // blue
                        break;
                case 2:
                        attrset(COLOR_PAIR(3)); //green
                        break;
                case 3:
                        // cyan -- not used on this cyan background
                        break;
                case 4:
                        attrset(COLOR_PAIR(4)); //red
                        break;
                case 5:
                        attrset(COLOR_PAIR(5)); //magenta
                        break;
                case 6:
                        attrset(COLOR_PAIR(6)); //brown
                        break;
                case 7:
                        attrset(COLOR_PAIR(7)); //white
                        break;
                case 8:
                        attrset(COLOR_PAIR(1)|A_BOLD); //gray
                        break;
                case 9:
                        attrset(COLOR_PAIR(2)|A_BOLD); //light blue
                        break;
                case 10:
                        attrset(COLOR_PAIR(3)|A_BOLD); //light green
                        break;
                case 11:
                        // light cyan -- not used on this cyan background
                        break;
                case 12:
                        attrset(COLOR_PAIR(4)|A_BOLD); // light red
                        break;
                case 13:
                        attrset(COLOR_PAIR(5)|A_BOLD); // light magenta
                        break;
                case 14:
                        attrset(COLOR_PAIR(6)|A_BOLD); // yellow
                        break;
                case 15:
                        attrset(COLOR_PAIR(7)|A_BOLD); // high intensity white
                        break;
                }
        return;
        }

NCURSES BOX DRAWING FUNCTION

A simple function to draw a box.

void drawbox(const int y, const int x, const int width, const int height)
        //width and height must be at least 2 to allow for top and bottom line
        {
        int counter;
        mvaddch(y,x,ACS_ULCORNER);
        for (counter=2; counter < width; counter++)
                addch(ACS_HLINE);
        addch(ACS_URCORNER);
        for (counter=1; counter < height-1; counter++)
                {
                mvaddch(y+counter,x,ACS_VLINE);
                mvaddch(y+counter,x+width-1,ACS_VLINE);
                }
        mvaddch(y+height-1,x,ACS_LLCORNER);
        for (counter=2; counter < width; counter++)
                addch(ACS_HLINE);
        addch(ACS_LRCORNER);
        return;
        }

GEANY – A Lightweight IDE & Programmer's Editor

If you are looking for an excellent programmer's editor, I use and highly recommend Geany (homepage). Geany is a lightweight IDE that should run on most Linux and Unix systems, and apparently it even runs on Microsoft Windows. It requires only the GTK2 runtime libraries.

You can download precompiled Geany rpms for Centos 5, both x86_64 and i386 versions, from my “Assorted RPMS for Centos 5” page. You can download Geany for everything else here.

I am not associated in any way with the developers of Geany, other than the fact that I use and really like their editor.


Other articles written by Frank Cox can be found here.

Frank Cox owns and operates the Melville Theatre in Melville, Saskatchewan, Canada, and has been playing with computers for over 30 years.

Creative Commons License
This work is licensed under a Creative Commons Attribution-Share Alike 2.5 Canada License.