# # Name: bjr # Date: 5 sep 2016 # # Note: Makefiles begin with a capital M # Indentation MUST be with a tab # # tagets build, test, clean and submit are required. # COPTS= build: make ringbuf ringbuf: ringbuf.c ringbuf-sub.o ringbuf.h cc ${COPTS} -o $@ ringbuf-sub.o $< ringbuf-sub.o: ringbuf-sub.c ringbuf.h cc ${COPTS} -c -o $@ $< test: ringbuf -rm ringbuf.out ./ringbuf +abcdefghijklmno+pq-rs--tuv+ > ringbuf.out diff ringbuf.out ringbuf.ref clean: -rm ringbuf ringbuf-sub.o ringbuf.out
/* * name: * date: * * header file for ringbuf.c and ringbuf-sub.h * */ #define RINGBUF_SIZE 16 struct RingBuf { int head ; int tail ; int is_full ; char ringbuf[RINGBUF_SIZE] ; } ; /* globals shared between ringbuf.c and ringbuf-sub.c */ extern int g_debug ; extern int is_verbose ; /* the ringbuf "API" */ #define RB_Q_SIZE 0 #define RB_IS_EMPTY 1 #define RB_IS_FULL 2 #define RB_Q_COUNT 3 int rb_ioctl(int op) ; int rb_enqueue(int ele) ; int rb_dequeue(void) ;
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<unistd.h> #include<assert.h> #include "ringbuf.h" /* * author: * date: * pledge: this is my own work, unless otherwise noted * * update: */ /* static variables (zeroed) */ int g_debug = 0 ; int is_verbose = 0 ; struct RingBuf rb ; int rb_ioctl(int op) { switch (op) { case RB_Q_SIZE: return RINGBUF_SIZE ; case RB_IS_EMPTY: return 1 ; case RB_IS_FULL: case RB_Q_COUNT: default: ; } return 0 ; } int rb_enqueue(int ele) { /* given element ele of type char, enqueues on the ring buffer. if successful return ele, else return -1. */ return 0 ; } int rb_dequeue(void) { /* dequeue on the ring buffer. if successful return ele, else return -1. */ return -1 ; }
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<unistd.h> #include<assert.h> #include "ringbuf.h" /* * author: bjr * date: 5 sep 2016 * pledge: this is my own work, unless otherwise noted * * this is a template. change "author" and continue work * * update: */ /* globals go here */ extern int g_debug ; extern int is_verbose ; /* defines go here, in SHOUTY_CASE */ #define USAGE_MESSAGE "usage: ringbuf [-v] _commands_" int main(int argc, char * argv[]) { int is_verbose = 0 ; int ch ; char * ops ; int res ; while ((ch = getopt(argc, argv, "v")) != -1) { switch(ch) { case 'v': is_verbose = 1 ; break ; default: printf("%s\n", USAGE_MESSAGE) ; return 0 ; } } argc -= optind; argv += optind; /* example of an assertion */ assert(is_verbose==0 || is_verbose==1) ; if ( is_verbose ) { printf("%s:%d argc=%d\n", __FILE__, __LINE__, argc) ; if (argc!=0) { printf("%s:%d argument = |%s|\n", __FILE__, __LINE__, argv[0] ) ; } printf("%s:%d ringbuffer size = %d\n", __FILE__, __LINE__, rb_ioctl(RB_Q_SIZE) ) ; } if (!argc) { printf("%s\n", USAGE_MESSAGE) ; return 0 ; } ops = argv[0] ; while (*ops) { switch (*ops) { case '-': // ** HINT: res should be the result of a call to rb_dequeue res = -1 ; // ** if ( res==-1 ) { printf("deq: empty\n") ; } else { printf("deq: %c\n", res) ; } break ; case '+': printf("ioc: %d %d %d %d\n", // ** HINT: the first -1 is replaced by rb_iotcl(RB_Q_SIZE) -1, -1, -1, -1 ) ; // ** break ; default: // ** HINT: the next line is replaced by a call to rb_enqueue. the character // to enqueue is pointed to by ops. res = -1 ; // ** if ( res==-1 ) { printf("enq: full\n") ; } else { printf("enq: %c\n", *ops) ; } } // ** HINT: the next line should increment the character pointer ops ops ; // ** } return 0 ; }
ioc: 16 1 0 0 enq: a enq: b enq: c enq: d enq: e enq: f enq: g enq: h enq: i enq: j enq: k enq: l enq: m enq: n enq: o ioc: 16 0 0 15 enq: p enq: full deq: a enq: r enq: full deq: b deq: c enq: t enq: u enq: full ioc: 16 0 1 16
author: burton rosenberg
created: 03 sep 2021
update: 03 sep 2021