packages feed

alsa-pcm-0.6: src/Sound/ALSA/PCM/Core/Params.h

#include <stdlib.h>
#include <stdarg.h>

typedef char bool;
const bool false = 0, true = 1;

enum context {pcm_params, params_only};

void make_camel_case (char *dst, const char *src) {
  while (*src != 0) {
    if (*src == '_') {
      src ++;
      if (*src == 0) {break;}
      *dst = *src - ('a'-'A'); // assumes that 'a'>'A'
    } else {
      *dst = *src;
    }
    src++;
    dst++;
  }
  *dst = 0;
}

void init_comma (bool *comma) {
  *comma = false;
}

void print_comma (bool *comma) {
  if (*comma) {
    printf(", ");
  }
  *comma = true;
}

struct type {
  char *convert;
  char *hsname;
  char *cname;
};

enum param_direction {dir_in, dir_out, dir_inout};

struct parameter {
  struct type *type;
  char *name;
  enum param_direction dir;
};

struct parameter *in (struct type* t, char *name) {
  struct parameter *p = malloc (sizeof(struct parameter));
  p->type = t;
  p->name = name;
  p->dir = dir_in;
  return p;
}

struct parameter *out (struct type* t, char *name) {
  struct parameter *p = malloc (sizeof(struct parameter));
  p->type = t;
  p->name = name;
  p->dir = dir_out;
  return p;
}

struct parameter *inout (struct type* t, char *name) {
  struct parameter *p = malloc (sizeof(struct parameter));
  p->type = t;
  p->name = name;
  p->dir = dir_inout;
  return p;
}


struct type bool_p = {"boolConv", "Bool", "Bool_"};

struct type uint_p = {"Conv.int", "Word", "C.CUInt"};

struct type rate_p = {"Conv.int", "SampleFreq", "C.CUInt"};

struct type time_p = {"Conv.int", "Time", "C.CUInt"};

struct type direction_p = {"ordConv", "Ordering", "Direction"};

struct type uframes_p = {"Conv.int", "Size", "C.CUInt"};

struct type access_p = {"Conv.id", "Access", "Access"};

struct type format_p = {"Conv.id", "Format", "Format"};

struct type subformat_p = {"Conv.id", "Subformat", "Subformat"};

enum result {noresult, boolresult, uintresult, errnoresult, checked};


void hsc_accessor (enum result res, const char *name, enum context ctx, ...) {
  va_list arg;
  struct parameter *p;
  bool comma;
  char *camelName = alloca (strlen (name) + 1);
  make_camel_case (camelName, name);

  printf("foreign import ccall safe \"alsa/pcm.h snd_pcm_hw_params_%s\"\n",
         name);
  printf("   %s_ :: ", camelName);
  if (ctx==pcm_params) {
//    printf("Ptr (Struct i y) -> Ptr Params -> ");
    printf("Handle i y -> Ptr Params -> ");
  } else {
    printf("Ptr Params -> ");
  }

  va_start (arg, ctx);
  while (p = va_arg (arg, struct parameter *)) {
    if (p->dir == dir_in) {
      printf("%s -> ", p->type->cname);
     } else {
      printf("Ptr %s -> ", p->type->cname);
    }
  }
  va_end (arg);

  printf("IO ");
  if (res == noresult) {
    printf("()");
  } else if (res == errnoresult) {
    printf("E.Errno");
  } else {
    printf("C.CInt");
  }
  printf("\n\n");

  printf("%s :: ", camelName);

  va_start (arg, ctx);
  while (p = va_arg (arg, struct parameter *)) {
    if (p->dir != dir_out) {
      printf("%s -> ", p->type->hsname);
    }
  }
  va_end (arg);

  printf("T i y (");
  init_comma(&comma);
  if (res == uintresult) {
    print_comma(&comma);
    printf("Word");
  } else if (res == errnoresult) {
    print_comma(&comma);
    printf("E.Errno");
  } else if (res == boolresult) {
    print_comma(&comma);
    printf("Bool");
  }
  va_start (arg, ctx);
  while (p = va_arg (arg, struct parameter *)) {
    if (p->dir != dir_in) {
      print_comma(&comma);
      printf("%s", p->type->hsname);
    }
  }
  va_end (arg);
  printf(")\n");

  printf("%s", camelName);
  va_start (arg, ctx);
  while (p = va_arg (arg, struct parameter *)) {
    if (p->dir != dir_out) {
      printf(" %s", p->name);
    }
  }
  va_end (arg);
  printf(" =\n");

  if (ctx==pcm_params) {
//    printf("   Cons $ \\(Handle h) p ->\n");
    printf("   Cons $ \\h p ->\n");
  } else {
    printf("   Cons $ \\ _ p ->\n");
  }
  va_start (arg, ctx);
  while (p = va_arg (arg, struct parameter *)) {
    if (p->dir == dir_out) {
      printf("   alloca $ \\%sPtr ->\n", p->name);
    } else if (p->dir == dir_inout) {
      printf("   Conv.with %s %s $ \\%sPtr ->\n",
         p->type->convert, p->name, p->name);
    }
  }
  va_end (arg);

  printf("   %s_", camelName);
  if (ctx==pcm_params) {
    printf(" h p");
  } else {
    printf(" p");
  }
  va_start (arg, ctx);
  while (p = va_arg (arg, struct parameter *)) {
    if (p->dir == dir_in) {
      printf(" (fromHaskell %s %s)",
                p->type->convert, p->name);
    } else {
      printf(" %sPtr", p->name);
    }
  }
  va_end (arg);
  if (res == uintresult) {
    printf(" >>=\n   checkResult \"HwParams.%s\" >>= \\res ->\n", camelName);
  } else if (res == boolresult || res == errnoresult) {
    printf(" >>= \\res ->\n");
  } else if (res == checked) {
    printf(" >>=\n   checkResult_ \"HwParams.%s\" >>\n", camelName);
  } else {
    printf(" >>\n");
  }

  va_start (arg, ctx);
  while (p = va_arg (arg, struct parameter *)) {
    if (p->dir != dir_in) {
      printf("   Conv.peek %s %sPtr >>= \\%sResult ->\n",
         p->type->convert, p->name, p->name);
    }
  }
  va_end (arg);

  printf("   return (");
  init_comma(&comma);
  if (res == uintresult) {
    print_comma(&comma);
    printf("fromIntegral res");
  } else if (res == errnoresult) {
    print_comma(&comma);
    printf("res");
  } else if (res == boolresult) {
    print_comma(&comma);
    printf("res/=0");
  }
  va_start (arg, ctx);
  while (p = va_arg (arg, struct parameter *)) {
    if (p->dir != dir_in) {
      print_comma(&comma);
      printf("%sResult", p->name);
    }
  }
  va_end (arg);
  printf(")\n");
}