Advertisement
Guest User

libastral

a guest
Jan 29th, 2014
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.02 KB | None | 0 0
  1. /*
  2.  * ----------------------------------------------------------------------------
  3.  * "THE MODIFIED BEER-WARE LICENSE" (Revision 1):
  4.  * <zmey20000@yahoo.com> wrote this file. As long as you retain this notice you
  5.  * can do whatever you want with this stuff. If we meet some day, and you think
  6.  * this stuff is worth it, you can buy me a beer in return Mikhail E. Zakharov
  7.  * ----------------------------------------------------------------------------
  8.  */
  9.  
  10. #ifndef __ASTRAL_LIB_H_
  11. #define __ASTRAL_LIB_H_
  12.  
  13. /* ASTRAL API top-level functions */
  14. struct portal* astral_open();
  15. int astral_close(struct portal *p);
  16. int astral_listen(struct portal *p, char *voice_divine);
  17. /* int astral_pray(struct portal *p, char* pray); */
  18.  
  19. /* ASTRAL low-level API */
  20. #define LETTERS_MIN     1
  21. #define LETTERS_MAX     10
  22. #define WORDS_MIN       1
  23. #define WORDS_MAX       16
  24. #define SENTANCES_MIN       1
  25. #define SENTANCES_MAX       8
  26. #define PARAGRAPHS_MIN      1
  27. #define PARAGRAPHS_MAX      4
  28.  
  29. #define WORD_MAX_LENGTH     (LETTERS_MAX + 1)
  30. #define SENTANCE_MAX_LENGTH (WORDS_MAX * WORD_MAX_LENGTH + 1) /* "Blah-blah-blah. " <--dot-space */
  31. #define PARAGRAPH_MAX_LENGTH    (SENTANCES_MAX * SENTANCE_MAX_LENGTH + 90)
  32. #define STATEMENT_MAX_LENGTH    PARAGRAPHS_MAX * (PARAGRAPH_MAX_LENGTH) /* 99. Foo-bar."\n\n" */
  33.  
  34. #define WORD_STYLE_SIMPLE   0
  35. #define WORD_STYLE_NAME     1
  36. #define WORD_STYLE_TITLE    2
  37.  
  38. #define SENTANCE_STYLE_SIMPLE   0  
  39. #define SENTANCE_STYLE_TITLE    1
  40.  
  41. #define VOICE_STYLE_SIMPLE  0
  42. #define VOICE_STYLE_BIBLE   1
  43. #define VOICE_STYLE_BIBLE_LNLEN 32 
  44.  
  45. struct portal {
  46.     int gate;
  47.  
  48.         int l_min;
  49.         int l_max;
  50.         int w_min;
  51.         int w_max;
  52.         int s_min;
  53.         int s_max;
  54.         int p_min;
  55.         int p_max;
  56.        
  57.     int w_style;
  58.     int s_style;
  59.         int v_style;
  60.  
  61.         int st_bible_lnlen;
  62. };
  63.  
  64.  
  65. int astral_rand(int gate, int min, int max);
  66. char astral_listen_letter(struct portal *p);
  67. int astral_listen_word(struct portal *p, char* word_divine);
  68. int astral_listen_sentance(struct portal *p, char* sentance_divine);
  69. int astral_listen_paragraph(struct portal *p, char* paragraph_divine);
  70.  
  71. #endif /* __ASTRAL_LIB_H_ */
  72.  
  73. //----------------------------------------------------------------------------------------
  74.  
  75. /*
  76.  * ----------------------------------------------------------------------------
  77.  * "THE MODIFIED BEER-WARE LICENSE" (Revision 1):
  78.  * <zmey20000@yahoo.com> wrote this file. As long as you retain this notice you
  79.  * can do whatever you want with this stuff. If we meet some day, and you think
  80.  * this stuff is worth it, you can buy me a beer in return Mikhail E. Zakharov
  81.  * ----------------------------------------------------------------------------
  82.  */
  83.  
  84. #include "libastral.h"
  85.  
  86. #include <stdio.h>
  87. #include <sys/types.h>
  88. #include <sys/stat.h>
  89. #include <fcntl.h>
  90. #include <stdlib.h>
  91. #include <unistd.h>
  92. #include <string.h>
  93. #include <ctype.h>
  94.  
  95. #define version "libastral-0.5"
  96.  
  97. /* -------------------------------------------------------------------------- */
  98. struct portal* astral_open() {
  99.     struct portal *p;
  100.  
  101.     p = (struct portal *)malloc(sizeof(struct portal));
  102.  
  103.     if ((p->gate = open("/dev/urandom", O_RDONLY)) == -1) {
  104.         fprintf(stderr, "astral_open() failed\n");
  105.         free(p);
  106.         exit(1);
  107.     }
  108.  
  109.     /* init portal values */
  110.     p->l_min = LETTERS_MIN;
  111.     p->l_max = LETTERS_MAX;
  112.     p->w_min = WORDS_MIN;
  113.     p->w_max = WORDS_MAX;
  114.     p->s_min = SENTANCES_MIN;
  115.     p->s_max = SENTANCES_MAX;
  116.     p->p_min = PARAGRAPHS_MIN;
  117.     p->p_max = PARAGRAPHS_MAX;
  118.     p->w_style = WORD_STYLE_SIMPLE;
  119.     p->s_style = SENTANCE_STYLE_SIMPLE;
  120.     p->v_style = VOICE_STYLE_BIBLE;
  121.     p->st_bible_lnlen = VOICE_STYLE_BIBLE_LNLEN;
  122.  
  123.     return p;
  124. }
  125.  
  126. /* -------------------------------------------------------------------------- */
  127. int astral_close(struct portal *p) {
  128.     if (close(p->gate) == -1) {
  129.         fprintf(stderr, "astral_close() failed\n");
  130.         free(p);
  131.         exit(1);
  132.     }
  133.  
  134.     free(p);
  135.     return 0;
  136. }
  137.  
  138. /* -------------------------------------------------------------------------- */
  139. int astral_rand(int gate, int min, int max) {
  140.     unsigned int fortune;
  141.  
  142.     read(gate, &fortune, 1);
  143.     srandom(fortune);
  144.  
  145.     return min + (int)(max * (random() / (RAND_MAX + 1.0)));
  146. }
  147. /* -------------------------------------------------------------------------- */
  148. char astral_listen_letter(struct portal *p) {
  149.     char letter_divine;
  150.  
  151.     do
  152.         if (read(p->gate, &letter_divine, 1) == -1) {
  153.             fprintf(stderr, "astral_listen_letter() failed\n");
  154.             exit(1);
  155.         }
  156.     while
  157.         (letter_divine < 97 || letter_divine > 122);
  158.  
  159.     return letter_divine;
  160. }
  161. /* -------------------------------------------------------------------------- */
  162. int astral_listen_word(struct portal *p, char* word_divine) {
  163.     int l, w_len;
  164.     char letter;
  165.  
  166.     /* word-divine length in letters */
  167.     w_len = astral_rand(p->gate, p->l_min, p->l_max);
  168.     memset(word_divine, 0, LETTERS_MAX);
  169.  
  170.     for (l = 0; l < w_len; l++) {
  171.         letter = astral_listen_letter(p);
  172.         switch (p->w_style) {
  173.             case WORD_STYLE_SIMPLE:
  174.                 break;
  175.             case WORD_STYLE_NAME:
  176.                 letter = toupper(letter);
  177.                 p->w_style = WORD_STYLE_SIMPLE;
  178.                 break;
  179.             case WORD_STYLE_TITLE:
  180.                 letter = toupper(letter);
  181.         }
  182.         strncat(word_divine, &letter, 1);
  183.     }
  184.  
  185.     return w_len;
  186. }
  187. /* -------------------------------------------------------------------------- */
  188. int astral_listen_sentance(struct portal *p, char* sentance_divine) {
  189.     int l, s_len, w_len;
  190.     char word_divine[WORD_MAX_LENGTH];
  191.  
  192.     /* sentance-divine length in words */
  193.     s_len = astral_rand(p->gate, p->w_min, p->w_max);
  194.     memset(sentance_divine, 0, SENTANCE_MAX_LENGTH);
  195.  
  196.     switch (p->s_style) {
  197.         case SENTANCE_STYLE_SIMPLE:
  198.             p->w_style = WORD_STYLE_NAME;
  199.             w_len = astral_listen_word(p, word_divine);
  200.             strncat(sentance_divine, word_divine, w_len);
  201.             p->w_style = WORD_STYLE_SIMPLE;
  202.             break;
  203.         case SENTANCE_STYLE_TITLE:
  204.             p->w_style = WORD_STYLE_TITLE;
  205.             w_len = astral_listen_word(p, word_divine);
  206.             break;
  207.     }
  208.  
  209.     /* The rest of the sentance */
  210.     for (l = 1; l < s_len; l++) {
  211.         w_len = astral_listen_word(p, word_divine);
  212.         strncat(sentance_divine, word_divine, w_len);
  213.         if (l + 1 == s_len)
  214.             strncat(sentance_divine, ".", 1);
  215.         else
  216.             strncat(sentance_divine, " ", 1);          
  217.     }
  218.    
  219.     return strlen(sentance_divine);
  220. }
  221.  
  222. /* -------------------------------------------------------------------------- */
  223. int astral_listen_paragraph(struct portal *p, char* paragraph_divine) {
  224.     int l, p_len, s_len;
  225.     char sentance_divine[SENTANCE_MAX_LENGTH];
  226.  
  227.     /* paragraph-divine length in sentances */
  228.     p_len = astral_rand(p->gate, p->s_min, p->s_max);
  229.     memset(paragraph_divine, 0, PARAGRAPH_MAX_LENGTH);
  230.  
  231.     for (l = 0; l < p_len; l++) {
  232.         s_len = astral_listen_sentance(p, sentance_divine);
  233.         strncat(paragraph_divine, sentance_divine, s_len);
  234.         if (l + 1 < p_len)
  235.             strncat(paragraph_divine, " ", 1);
  236.     }
  237.     return strlen(paragraph_divine);
  238. }
  239.  
  240. /* -------------------------------------------------------------------------- */
  241. const char *strins(char *dst, char *ins, int pos) {
  242.     char *save;
  243.  
  244.     if (pos < strlen(dst)) {
  245.         save = (char *)malloc(strlen(dst) + 1);
  246.  
  247.         strcpy(save, dst + pos);
  248.         strcpy(dst + pos, ins);
  249.         strcat(dst, save);
  250.  
  251.         free(save);
  252.     } else
  253.         strcat(dst, ins);
  254.  
  255.     return dst;
  256. }
  257. /* -------------------------------------------------------------------------- */
  258. int astral_listen(struct portal *p, char *voice_divine) {
  259.     int l, i, v_len, p_len;
  260.     char paragraph[PARAGRAPH_MAX_LENGTH];
  261.     char paragraph_divine[PARAGRAPH_MAX_LENGTH];
  262.  
  263.     /* voice-divine length in sentances */
  264.     v_len = astral_rand(p->gate, p->p_min, p->p_max);
  265.     memset(voice_divine, 0, STATEMENT_MAX_LENGTH);
  266.  
  267.     for (l = 0; l < v_len; l++) {
  268.         p_len = astral_listen_paragraph(p, paragraph);
  269.         switch (p->v_style) {
  270.             case VOICE_STYLE_SIMPLE:
  271.                 sprintf(paragraph_divine, "%s\n\n", paragraph);
  272.                 break;
  273.             case VOICE_STYLE_BIBLE:
  274.                 for (i = p->st_bible_lnlen - 2;
  275.                     i < p_len;
  276.                     i += p->st_bible_lnlen, p_len += 2
  277.                 )
  278.                     strins(paragraph, "\n\t", i);
  279.  
  280.                 sprintf(paragraph_divine, "%d.\t%s\n\n", l + 1, paragraph);
  281.         }
  282.  
  283.         strncat(voice_divine, paragraph_divine, strlen(paragraph_divine));
  284.     }
  285.     return 0;
  286. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement