#03

// argdemo1.c --- print argc/argv as string
#include <stdio.h>
int main(int argc, char *argv[]) {
  for(int i = 0; i < argc; ++i) { printf("%s\n", argv[i]); }
  return 0;
}
// argdemo2.c --- sum of argument strings (as int)
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
  int sum = 0;
  for(int i = 1; i < argc; ++i) { sum += atof(argv[i]); }
  printf("sum = %d\n", sum);
  return 0;
}
// istack.h --- int type stack interface
#include <stdbool.h>
struct istack;
typedef struct istack *istackp;
istackp istack_new(int size); // allocate new stack
bool istack_isempty(istackp p); // test if the stack is empty
void istack_push(istackp p, int v); // push a value
int istack_pop(istackp p);      // pop a value and return it
int istack_top(istackp p);      // peek the topmost value
// istack.c --- int type stack impl. with array
#include <stdlib.h>
#include "istack.h"
struct istack { int ptr; int *arr; };
istackp istack_new(int size) {
  istackp p = (istackp)malloc(sizeof(struct istack));
  p->ptr = 0; p->arr = (int*)malloc(size * sizeof(int));
  return p;
}
bool istack_isempty(istackp p) { return p->ptr <= 0; }
void istack_push(istackp p, int v) { p->arr[p->ptr++] = v; }
int istack_pop(istackp p) { return p->arr[--(p->ptr)]; }
int istack_top(istackp p) { return p->arr[p->ptr - 1]; }
// reversestr.c --- print argv[1] in reverse order
#include <stdio.h>
#include <stdlib.h>
#include "istack.h"
int main(int argc, char *argv[]) {
  istackp s = istack_new(200);
  char *t = argv[1];
  for(int i = 0; t[i] != '\0'; ++i) { istack_push(s, t[i]); }
  while(!istack_isempty(s)) { putchar(istack_pop(s)); }
  putchar('\n');
  return 0;
}
// test_istack.c --- unit test for istack.
#include <stdio.h>
#include <stdlib.h>
#include "istack.h"
void expect_int(int i1, int i2, char *msg) {
  printf("%s %d:%d %s\n", (i1==i2)?"OK":"NG", i1, i2, msg);
}
int main(int argc, char *argv[]) {
  struct istack *s = istack_new(200);
  istack_push(s, 1); istack_push(s, 2); istack_push(s, 3);
  expect_int(istack_pop(s), 3, "push 1 2 3 ; pop");
  expect_int(istack_pop(s), 2, "pop");
  istack_push(s, 4);
  expect_int(istack_pop(s), 4, "push 4; pop");
  expect_int(istack_pop(s), 1, "pop");
  return 0;
}
// barance1.c --- see if parentheses are balanced in input
#include <stdio.h>
#include <stdlib.h>
#include "istack.h"
bool balance1(char *t) {
  istackp s = istack_new(200);
  for(int i = 0; t[i] != '\0'; ++i) {
    char c = t[i];
    if(c == '(') {
      istack_push(s, c);
    } else if(c == ')') {
      if(istack_isempty(s)) { return false; }
      istack_pop(s);
    }
  }
  return istack_isempty(s);
}
int main(int argc, char *argv[]) {
  for(int i = 1; i < argc; ++i) {
    printf("%s : %s\n", argv[i], balance1(argv[i])?"OK":"NG");
  }
  return 0;
}
// test_barance1.c --- unit test for balance1
#include <stdio.h>
#include <stdlib.h>
#include "istack.h"
char *bool2str(bool b) { return b ? "true" : "false"; }
void expect_bool(bool b1, bool b2, char *msg) {
  printf("%s %s:%s %s\n", (b1==b2)?"OK":"NG",
         bool2str(b1), bool2str(b2), msg);
}
bool balance1(char *t) {
  istackp s = istack_new(200);
  for(int i = 0; t[i] != '\0'; ++i) {
    char c = t[i];
    if(c == '(') {
      istack_push(s, c);
    } else if(c == ')') {
      if(istack_isempty(s)) { return false; }
      istack_pop(s);
    }
  }
  return istack_isempty(s);
}
int main(void) {
  expect_bool(balance1("((a)())"), true, "((a)())");
  expect_bool(balance1(")(a)()("), false, ")(a)()(");
  expect_bool(balance1("((a)()"), false, "((a)()");
  expect_bool(balance1("(a)())"), false, "(a)())");
  expect_bool(balance1("(((())))"), true, "(((())))");
  return 0;
}
// postfix1.c -- convert infix to postfix (w/o parentheses)
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "istack.h"
int operprec(int c) {
  switch(c) {
    case '+': case '-': return 1;
    case '*': case '/': case '%': return 2;
    case '^': return 3;
    default: return 0;
  }
}
void postfix1(char *t, char *u) {
  istackp s = istack_new(200);
  for(int i = 0; t[i] != '\0'; ++i) {
    char c = t[i];
    if(isdigit(c)) { *u++ = c; continue; }
    while(!istack_isempty(s) &&
          operprec(istack_top(s)) >= operprec(c)) {
      *u++ = istack_pop(s);
    }
    istack_push(s, c);
  }
  while(!istack_isempty(s)) { *u++ = istack_pop(s); }
  *u++ = '\0';
}
int main(int argc, char *argv[]) {
  char buf[200];
  for(int i = 1; i < argc; ++i) {
    postfix1(argv[i], buf);
    printf("%s => %s\n", argv[i], buf);
  }
  return 0;
}
// test_postfix1.c --- unit test of postfix1
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "istack.h"
int operprec(int c) {
  switch(c) {
    case '+': case '-': return 1;
    case '*': case '/': case '%': return 2;
    case '^': return 3;
    default: return 0;
  }
}
void postfix1(char *t, char *u) {
  istackp s = istack_new(200);
  for(int i = 0; t[i] != '\0'; ++i) {
    char c = t[i];
    if(isdigit(c)) { *u++ = c; continue; }
    while(!istack_isempty(s) &&
          operprec(istack_top(s)) >= operprec(c)) {
      *u++ = istack_pop(s);
    }
    istack_push(s, c);
  }
  while(!istack_isempty(s)) { *u++ = istack_pop(s); }
  *u++ = '\0';
}
void expect_str(char *s1, char *s2, char *msg) {
  printf("%s '%s':'%s' %s\n", strcmp(s1, s2)?"NG":"OK", s1, s2, msg);
}
int main(void) {
  char buf[200];
  postfix1("1+2*3", buf); expect_str(buf, "123*+", "1+2*3 => 123*+");
  postfix1("2*3+1", buf); expect_str(buf, "23*1+", "2*3+1 => 23*1+");
  return 0;
}
// pstack.h --- pointer type stack interface
#include <stdbool.h>
struct pstack;
typedef struct pstack *pstackp;
pstackp pstack_new(int size);
bool pstack_isempty(pstackp p);
bool pstack_isfull(pstackp p);
void pstack_push(pstackp p, void *v);
void *pstack_pop(pstackp p);
void *pstack_top(pstackp p);
// pstack.c --- pointer type stack impl. with array
#include <stdlib.h>
#include "pstack.h"
struct pstack { int ptr, lim; void **arr; };
pstackp pstack_new(int size) {
  pstackp p = (pstackp)malloc(sizeof(struct pstack));
  p->ptr = 0; p->lim = size; p->arr = (void**)malloc(size * sizeof(void*));
  return p;
}
bool pstack_isempty(pstackp p) { return p->ptr <= 0; }
bool pstack_isfull(pstackp p) { return p->ptr >= p->lim; }
void pstack_push(pstackp p, void *v) { p->arr[p->ptr++] = v; }
void *pstack_pop(pstackp p) { return p->arr[--(p->ptr)]; }
void *pstack_top(pstackp p) { return p->arr[p->ptr - 1]; }
// reversefile.c --- input a flie and output upside-down
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pstack.h"
bool getl(char s[], int lim) {
  int c, i = 0;
  for(c = getchar(); c != EOF && c != '\n'; c = getchar()) {
    s[i++] = c; if(i+1 >= lim) { break; }
  }
  s[i] = '\0'; return c != EOF;
}
int main(void) {
  char buf[200];
  pstackp s = pstack_new(200);
  while(getl(buf, 200)) {
    char *t = (char*)malloc(strlen(buf)+1);
    strcpy(t, buf); pstack_push(s, t);
  }
  while(!pstack_isempty(s)) {
    char *t = (char*)pstack_pop(s); printf("%s\n", t); free(t);
  }
  return 0;
}