Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

incomplete text editor in C

Name: Anonymous 2008-04-26 6:12

Supports buffers, with a few lines added supports regex, and pretty much any text manipulation as long as you provide the function to manipulate the text in some way.
It's in standard C so should compile everywhere.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>

#define MAXBUF    64

typedef struct _list {
    char buf[BUFSIZ];    /* text of line */
    size_t n;        /* sizeof text */
    struct _list *next;    /* next line */
} list;



typedef struct {

    list *lines;            /* actual lines in the file */
    size_t nlines;            /* number of lines in the file */
    FILE *stream;            /* stream we edit, if a stream is present */
    char name[FILENAME_MAX+1];    /* name of stream, or anonymous */

#define FBUF_A 0
#define FBUF_R 1
#define FBUF_W 2
    int mode;            /* read/write/anon buf */

    size_t curline;            /* current line we operate on */

} filebuf;

struct foo {

    filebuf *fbuf[MAXBUF];
    size_t nbuf;
    size_t curbuf;

};

typedef int cmdfunc(const char *, struct foo *);


#define funcname(x) (CMD_##x)

#define getname(x) ((x)->name[0] == 0 ? "[noname]" : (const char *)(x)->name)
void setname(filebuf *, const char *);
filebuf *newbuf(const char *);
int addbuf(struct foo *, const char *);
void killbuf(filebuf *);
void rembuf(struct foo *, size_t);
void destroylist(list *);
void destroyfiles(struct foo *);

int cmd_exec(const char *, struct foo *);
int cmd_result(FILE *, int);
void getword(char *, const char *);
int changebuf(struct foo *, size_t);
int changeline(filebuf *, size_t);
void printbufname(const struct foo *, size_t);

/* CMD commands */

cmdfunc funcname(ls);
cmdfunc funcname(b);

int main(int argc, char **argv) {

    size_t i = 0;
    struct foo files;
    int ret;
    char buf[BUFSIZ];
    char *p, *s;
    const char *prompt = "> ";

    if(argc < 2)
        return 0;

    memset(&files, 0, sizeof files);

    for(i = 1; i < (size_t)argc; i++) {
        ret = addbuf(&files, argv[i]);
        if(ret == -1)
            perror(argv[i]);
        else if(ret == 1)
            fprintf(stderr, "too many buffers. (%lu)\n", (unsigned long)MAXBUF);
        else printf("opened %s\n", argv[i][0] == 0 ? "[noname]" : argv[i]);

    }

    printf("%s", prompt);
    fflush(stdout);

    while(fgets(buf, sizeof buf, stdin) != NULL) {

        ret = 0;

        for(p = buf;  *p; p = s + 1) {
            s = strpbrk(p, ";\n");
            if(s != NULL)
                *s = 0;

            if((ret = cmd_exec(p, &files)) != 0)
                fprintf(stderr, "%lu %s: ", (unsigned long)files.curbuf, getname(files.fbuf[files.curbuf]));
           
            cmd_result(stderr, ret);
            printf("%s", prompt);
            fflush(stdout);
        }
    }
   
    destroyfiles(&files);
    putchar('\n');

    return 0;
}

int funcname(ls)(const char *str, struct foo *files) {

    size_t n;

    (void)str;

    for(n = 0; n < files->nbuf; n++)
        printbufname(files, n);

    return 0;
}


int funcname(b)(const char *str, struct foo *files) {

    const char *p;

    if(*str == 0) {
        printbufname(files, files->curbuf);
        return 0;
    }

    for(p = str; *p && isdigit((unsigned char)*p); p++)
        ;
    if(*p != 0 && !isspace((unsigned char)*p)) {
        /*
           EDIT HERE
           return bad buf id
         */
        return -1;
    }

    return    changebuf(files, atoi(str));
}

void printbufname(const struct foo *files, size_t id) {

    printf("%lu %s\n", (unsigned long)id, getname(files->fbuf[id]));
}


int changeline(filebuf *file, size_t id) {

    if(id >= file->nlines)
        return -1;

    file->curline = id;
    return 0;
}

int cmd_result(FILE *out , int ret) {

    if(ret != 0)
        fprintf(out, "some error\n");

    return 0;

}

int changebuf(struct foo *files, size_t id) {

    if(id < files->nbuf) {
        files->curbuf = id;
        return 0;
    }
    /* EDIT HERE
       return BADBUFID
       */
    else return -1;

}

void getword(char *buf, const char *str) {
   
    char *p;

    p = strchr(str, ' ');
    if(p == NULL)
        strcpy(buf, str);
    else {
        strncpy(buf, str, p - str);
        buf[p - str] = 0;
    }


}

int cmd_exec(const char *str, struct foo *files) {

    char buf[BUFSIZ];
    size_t n;

    /* EDIT HERE */

    struct {
        const char *cmd;
        cmdfunc *f;
    } commands[] = {
        { "ls", funcname(ls) },
        { "b", funcname(b) }
    };

    getword(buf, str);

    for(n = 0; n < sizeof commands / sizeof commands[0]; n++)
        if(strcmp(buf, commands[n].cmd) == 0)
            return commands[n].f(str + strlen(buf) + 1, files);

    /* EDIT HERE
       return BAD COMMAND
       */

    return -1;

}

void destroyfiles(struct foo *files) {
   
    size_t i;
   
    for(i = files->nbuf - 1; i != (size_t)-1; i--) {
#ifdef TED_DEBUG
        printf("filename: '%s'\n", getname(files->fbuf[i]));
        printf("mode opened: %d\n", files->fbuf[i]->mode);
        printf("%p\n", (void *)files->fbuf[i]->lines);
#endif
        rembuf(files, i);

    }

}
void setname(filebuf *file, const char *name) {

    memset(file->name, 0, sizeof file->name);
    if(name != NULL)
        strncpy(file->name, name, sizeof file->name - 1);
}

void rembuf(struct foo *ptr, size_t n) {

    if(n > ptr->nbuf)
        return;

    killbuf(ptr->fbuf[n]);

    if(n != ptr->nbuf)
        memmove(&ptr->fbuf[n], &ptr->fbuf[n + 1],
                (ptr->nbuf - n) * sizeof ptr->nbuf);
    ptr->nbuf--;


}


void killbuf(filebuf *file) {

    if(file->stream != NULL) {
        fflush(file->stream);
        fclose(file->stream);
    }

    destroylist(file->lines);

}

void destroylist(list *lines) {
    list *p = NULL;

    if(lines)
        p = lines->next;
    free(lines);

    while(p != NULL) {
        lines = p->next;
        free(p);
        p = lines;
    }

}

filebuf *newbuf(const char *path) {

    filebuf *ret;
    FILE *fp;
    int mode;
    char buf[BUFSIZ];
    list **p;

    if(path != NULL && *path != 0) {

        fp = fopen(path, "r+");
        mode = FBUF_W;
        if(fp == NULL) {
            fp = fopen(path, "r");
            mode = FBUF_R;
        }
        if(fp == NULL) {
            fp = fopen(path, "w");
            mode = FBUF_W;
        }
   
        if(fp == NULL)
            return NULL;
   
        ret = malloc(sizeof *ret);
        if(ret == NULL) {
            fclose(fp);
            return NULL;
        }
    }
    else {
        fp = NULL;
        mode = FBUF_A;
        ret = malloc(sizeof *ret);
        if(ret == NULL)
            return NULL;
    }

    memset(ret, 0, sizeof *ret);

    ret->mode = mode;
    ret->stream = fp;


    p = &ret->lines;

    /* in case of anonbuf
       curline = 0, nlines = 0
       which is the same with opening an empty file
       !FIX!
       */

    while(fp && fgets(buf, sizeof buf, fp) != NULL) {

        *p = malloc(sizeof **p);

        if(*p == NULL) {
            free(ret);
            fclose(fp);
            return NULL;
        }
       
        (*p)->next = NULL;
        strcpy((*p)->buf, buf);
        (*p)->n = strlen(buf);
        p = &(*p)->next;
        ret->nlines++;
    }

    return ret;

}

int addbuf(struct foo *files, const char *path) {


    if(files->nbuf != MAXBUF) {
        files->fbuf[files->nbuf] = newbuf(path);
        if(files->fbuf[files->nbuf] == NULL)
            return -1;
        setname(files->fbuf[files->nbuf], path);
        files->nbuf++;
        return 0;
    }
    return 1;
}

Name: Anonymous 2008-04-26 6:44

>>1
One word, the incomprehensible addition of blank lines.

Name: Anonymous 2008-04-26 7:30

    returnchangebuf(files, atoi(str));

Name: Anonymous 2008-04-26 7:30

>>3
Oh, fuck you shiitchan.

Name: Anonymous 2008-04-26 7:33

>>3
Why did you remove the space between return and the function?
Anyway, that's correct. atoi() will not produce unpredictable results because of the checks before on str with isdigit.

Name: Anonymous 2008-04-26 7:39

>>5
I didn't, I was trying to highlight the giant space between "return" and "changebuf", but shiichan ate it because it's retarded.

Name: Anonymous 2008-04-26 7:54

>>6
Yeah I used a tab for some reason. I have no idea why and I never do that, so I changed it in my original code.
Damn, shiichan sucks.

Name: Anonymous 2008-04-26 15:21

If you would like to report a bug with the Shiichan software please contact Avery `Shii' Morrow, http://gridley.res.carleton.edu/~morrowa/ <morrowa@carleton.edu>;

Name: Anonymous 2008-04-26 15:44

A complete text editor in Brainfuck:
+[[,][-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.[-]+++++++++++++.---.+]

Name: Anonymous 2008-04-26 16:39

>>1
ED! ED IS THE STANDARD

Name: Anonymous 2008-04-26 17:24

Name: Anonymous 2008-04-26 18:08

>>9
NO
a complete editor in hax my anus

hax hax anus my anus hax anus anus anus my anus my anus hax

Name: Anonymous 2008-04-27 3:46

Bump, you'd see a fizzbuzz to be discussed more here :(

Name: Anonymous 2008-04-27 15:34

>>13
what

Name: Anonymous 2008-04-27 15:36

>>13
Nobody cares about your shiteditor because there are already awesome editors available. Got it?

Name: Anonymous 2008-04-27 15:47

>>15
80s abandonware are not text editors.

Name: Anonymous 2008-04-27 15:57

>>16
emacs user, i'm trying out vim. use '>>' and '<<' to indent and de-indent wow, thanks. hax my anus hax my anus hax my anus hax my anus hax my anus hax my anus hax my anus hax my anus hax my anus hax my anus

Name: Anonymous 2008-04-28 21:59

Incomplete database server in C:

#include <stdlib.h>

int main(int argc, char **argv)


End.

Name: Anonymous 2008-04-28 22:52

When I use an editor, I don't want eight extra KILOBYTES of worthless
help screens
and cursor positioning code!  I just want an EDitor!!
Not a "viitor".  Not a "emacsitor".  Those aren't even WORDS!!!!
ED! ED! ED IS THE STANDARD!!!

Name: Anonymous 2009-03-06 6:16

The first programming language   Python 8 The   first programming language   but not the   panacea of programming   made the bald   and unvarnished statement.

Name: Anonymous 2009-03-06 14:37

The functional programming part.

Name: Sgt.Kabukiman䖉 2012-05-22 23:26

All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy
 All work and no play makes Jack a dull boy

Name: Anonymous 2012-05-22 23:27

>>19
Back to cat-v, ``please"!

Don't change these.
Name: Email:
Entire Thread Thread List