Guest User

LAMP C STDIO

a guest
Sep 13th, 2013
32
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 14.13 KB | None | 0 0
  1. /*
  2.  *  This file is in the Public Domain.
  3.  *  This file has no warranties of any kind,
  4.  *  And can be distributed, modified or used freely.
  5.  *
  6.  *  Author: Vinyl Scratched
  7.  */
  8.  
  9. /*
  10.  *  This file uses the LAMP C syntax extensions Library.
  11.  *  The lamp header is required for this file to be compiled.
  12.  */
  13.  
  14. #include <ctype.h>
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include <stdarg.h>
  18. #include <stdlib.h>
  19. #include <console.h>
  20.  
  21. DECL(pchar_t, putchar)(
  22.         DECL(pchar_t, character)
  23.         ) {
  24.     _FRET write_char(character);
  25. }
  26.  
  27. DECL(pchar_t, puts)(
  28.         DECL(CONST _STR, str)
  29.         ) {
  30.     _FRET write_str(str);
  31. }
  32.  
  33. _TD FUNC(pchar_t, out_t)(
  34.         DECL(_STR, buffer),
  35.         DECL(pchar_t, character)
  36. );
  37.  
  38. _TD FUNC(pchar_t, outbulk_t)(
  39.         DECL(_STR, buffer),
  40.         DECL(CONST _STR, str)
  41. );
  42.  
  43. ENUM {
  44.     LJUSTIFY    = 0,
  45.     FORCE_PLUS  = 1,
  46.     FORCE_SPACE = 2,
  47.     HASH_FLAG   = 3,
  48.     ZERO_FILL   = 4
  49. };
  50.  
  51. ENUM {
  52.     LMOD_NONE = ZERO,
  53.     LMOD_HH,
  54.     LMOD_H,
  55.     LMOD_L,
  56.     LMOD_LL,
  57.     LMOD_J,
  58.     LMOD_Z,
  59.     LMOD_T,
  60.     LMOD_LF
  61. };
  62.  
  63. HIDDEN INLINE
  64. DECL(byte_t, do_flags)(
  65.         DECL(CONST _STR, format),
  66.         DECL(value_t *, count)
  67.         ) {
  68.     DECL(byte_t, flags) = ZERO;
  69.     _IF(format[*count] == '-') {
  70.         SET_BIT(flags, LJUSTIFY);
  71.         *count += 1;
  72.     }
  73.     _IF(format[*count] == '+') {
  74.         SET_BIT(flags, FORCE_PLUS);
  75.         *count += 1;
  76.     }
  77.     _IF(format[*count] == ' ') {
  78.         SET_BIT(flags, FORCE_SPACE);
  79.         *count += 1;
  80.     }
  81.     _IF(format[*count] == '#') {
  82.         SET_BIT(flags, HASH_FLAG);
  83.         *count += 1;
  84.     }
  85.     _IF(format[*count] == ' ') {
  86.         SET_BIT(flags, FORCE_SPACE);
  87.         *count += 1;
  88.     }
  89.     _IF(format[*count] == '0') {
  90.         SET_BIT(flags, ZERO_FILL);
  91.         *count += 1;
  92.     }
  93.     _FRET flags;
  94. }
  95.  
  96. HIDDEN INLINE
  97. DECL(byte_t, do_width)(
  98.         DECL(CONST _STR, format),
  99.         DECL(value_t *, count)
  100.         ) {
  101.     DECL(byte_t, str)[9];
  102.     memset(str, ZERO, 9);
  103.     DECL(byte_t, pos) = ZERO;
  104.     DECL(byte_t, width) = ZERO;
  105.     _IF(isdigit(format[*count]) && format[*count] != '0') {
  106.         str[pos++] = format[*count]; *count += 1;
  107.         _WL(isdigit(format[*count])) {
  108.             _IF(pos >= 8) BREAK;
  109.             str[pos++] = format[*count];
  110.             *count += 1;
  111.         }
  112.         width = strtol((CONST _STR)str, ZERO, 10);
  113.     }
  114.     _FRET width;
  115. }
  116.  
  117. HIDDEN INLINE
  118. DECL(byte_t, do_lmod)(
  119.         DECL(CONST _STR, format),
  120.         DECL(value_t *, count)
  121.         ) {
  122.     DECL(byte_t, lmod);
  123.     _SW(format[*count]) {
  124.         /* End of Stream */
  125.         CASE ZERO: {   
  126.             _FRET ZERO;
  127.         }
  128.         /* short int */
  129.         CASE 'h': {
  130.             lmod = LMOD_H;
  131.             *count += 1;
  132.             /* short short int (char) */
  133.             _IF(format[*count] == 'h') {
  134.                 lmod = LMOD_HH;
  135.                 *count += 1;
  136.             }
  137.             BREAK;
  138.         }
  139.         /* long int */
  140.         CASE 'l': {
  141.             lmod = LMOD_L;
  142.             *count += 1;
  143.             /* long long int */
  144.             _IF(format[*count] == 'l') {
  145.                 lmod = LMOD_LL;
  146.                 *count += 1;
  147.             }
  148.             BREAK;
  149.         }
  150.         /* intmax_t */
  151.         CASE 'j': {
  152.             lmod = LMOD_J;
  153.             *count += 1;
  154.             BREAK;
  155.         }
  156.         /* size_t */
  157.         CASE 'z': {
  158.             lmod = LMOD_Z;
  159.             *count += 1;
  160.             BREAK;
  161.         }
  162.         /* ptrdiff_t */
  163.         CASE 't': {
  164.             lmod = LMOD_T;
  165.             *count += 1;
  166.             BREAK;
  167.         }
  168.         /* long double */
  169.         CASE 'L': {
  170.             lmod = LMOD_LF;
  171.             *count += 1;
  172.             BREAK;
  173.         }
  174.         /* None */
  175.         DEFT: {
  176.             lmod = LMOD_NONE;
  177.             BREAK;
  178.         }
  179.     }
  180.     _FRET lmod;
  181. }
  182.  
  183. HIDDEN INLINE
  184. DECL(_V, do_transform)(
  185.         DECL(out_t, out0),
  186.         DECL(outbulk_t, out1),
  187.         DECL(_STR, buffer),
  188.         DECL(length_t, length),
  189.         DECL(pchar_t *, total),
  190.         DECL(signed long long, value),
  191.         DECL(byte_t, flags),
  192.         DECL(byte_t, width),
  193.         DECL(byte_t, base),
  194.         DECL(_STR, tmp)
  195.         ) {
  196.     _IF(CHK_BIT(flags, FORCE_PLUS)) {
  197.         _IF(value >= ZERO && tmp[ZERO] != '-') {
  198.             *total += out0(buffer, '+');
  199.             _IF(*total >= (pchar_t)length) _FRET;
  200.         }
  201.     }
  202.     _IF(CHK_BIT(flags, HASH_FLAG)) {
  203.         _IF(base == 16) {
  204.             *total += out1(buffer, "0x");
  205.             _IF(*total >= (pchar_t)length) _FRET;
  206.         } _LS _IF(base == 8) {
  207.             *total += out1(buffer, "0o");
  208.             _IF(*total >= (pchar_t)length) _FRET;
  209.         } _LS _IF(base == 4) {
  210.             *total += out1(buffer, "0q");
  211.             _IF(*total >= (pchar_t)length) _FRET;
  212.         } _LS _IF(base == 2) {
  213.             *total += out1(buffer, "0b");
  214.             _IF(*total >= (pchar_t)length) _FRET;
  215.         }
  216.     }
  217.     _IF(CHK_BIT(flags, LJUSTIFY)) {
  218.         *total += out1(buffer, tmp);
  219.     }
  220.     _IF(CHK_BIT(flags, ZERO_FILL) ||
  221.             CHK_BIT(flags, FORCE_SPACE)) {
  222.         DECL(sdword_t, diff);
  223.         DECL(byte_t, ch) = CHK_BIT(flags, ZERO_FILL)
  224.                 ? '0' : ' ';
  225.         diff = width - strlen(tmp);
  226.         _WL(diff > ZERO) {
  227.             *total += out0(buffer, ch);
  228.             _IF(*total >= (pchar_t)length) _FRET;
  229.             diff--;
  230.         }
  231.     }
  232.     _IF(!CHK_BIT(flags, LJUSTIFY)) {
  233.         *total += out1(buffer, tmp);
  234.     }
  235. }
  236.  
  237. HIDDEN INLINE
  238. DECL(_V, handle_lhex)(
  239.         DECL(byte_t, lhex),
  240.         DECL(_STR, tmp)
  241.         ) {
  242.     _IF(lhex) {
  243.         _FI(dig, ZERO, 65) {
  244.             _IF(!tmp[dig]) BREAK;
  245.             tmp[dig] = tolower(tmp[dig]);
  246.         }
  247.     }
  248. }
  249.  
  250. HIDDEN
  251. DECL(pchar_t, do_printf)(
  252.         DECL(out_t, out0),
  253.         DECL(outbulk_t, out1),
  254.         DECL(_STR, buffer),
  255.         DECL(length_t, length),
  256.         DECL(CONST _STR, format),
  257.         DECL(va_list, args),
  258.         DECL(byte_t, term)
  259.         ) {
  260.     DECL(pchar_t, total) = ZERO;
  261.     _FI(count, ZERO, length) {
  262.         _IF(!format[count]) BREAK;
  263.         _IF(total > (pchar_t)length) BREAK;
  264.         _IF(format[count] == '%') {
  265.             DECL(byte_t, lhex) = ZERO;
  266.             DECL(byte_t, lmod) = ZERO;
  267.             DECL(byte_t, flags) = ZERO;
  268.             DECL(byte_t, width) = ZERO;
  269.             count += 1;
  270.             /* Modifier Flags */
  271.             flags = do_flags(format, &count);
  272.             /* Padding Width */
  273.             _IF(flags) {
  274.                 width = do_width(format, &count);
  275.             }
  276.             /* Length Modifier */
  277.             lmod = do_lmod(format, &count);
  278.             /* Specifier */
  279.             DECL(byte_t, base_val);
  280.             _SW(format[count]) {
  281.                 /* End of Stream */
  282.                 CASE ZERO: {
  283.                     BREAK;
  284.                 }
  285.                 /* Byte Count */
  286.                 CASE 'n': {
  287.                     DECL(pchar_t *, ptr);
  288.                     ptr = (pchar_t *)_VA(args, dword_t);
  289.                     ptr[ZERO] = total;
  290.                     BREAK;
  291.                 }
  292.                 /* Percent Sign */
  293.                 CASE '%': {
  294.                     total += out0(buffer, '%');
  295.                     BREAK;
  296.                 }
  297.                 /* Signed Integer */
  298.                 CASE 'd': CASE 'i':
  299.                     base_val = 10;
  300.                     _SW(lmod) {
  301.                         CASE LMOD_Z: {
  302.                             DECL(char, tmp)[33];
  303.                             DECL(size_t, value);
  304.                             value = _VA(args, size_t);
  305.                             ltoa(value, tmp, base_val);
  306.                             handle_lhex(lhex, tmp);
  307.                             do_transform(
  308.                                     out0, out1, buffer, length, &total,
  309.                                     (signed long long)value, flags,
  310.                                     width, base_val, tmp
  311.                             );
  312.                             BREAK;
  313.                         }
  314.                         CASE LMOD_J: {
  315.                             DECL(char, tmp)[65];
  316.                             DECL(intmax_t, value);
  317.                             value = _VA(args, intmax_t);
  318.                             lltoa(value, tmp, base_val);
  319.                             handle_lhex(lhex, tmp);
  320.                             do_transform(
  321.                                     out0, out1, buffer, length, &total,
  322.                                     (signed long long)value, flags,
  323.                                     width, base_val, tmp
  324.                             );
  325.                             BREAK;
  326.                         }
  327.                         CASE LMOD_HH: {
  328.                             DECL(char, tmp)[9];
  329.                             DECL(sbyte_t, value);
  330.                             value = (sbyte_t)_VA(args, sdword_t);
  331.                             ctoa(value, tmp, base_val);
  332.                             handle_lhex(lhex, tmp);
  333.                             do_transform(
  334.                                     out0, out1, buffer, length, &total,
  335.                                     (signed long long)value, flags,
  336.                                     width, base_val, tmp
  337.                             );
  338.                             BREAK;
  339.                         }
  340.                         CASE LMOD_H: {
  341.                             DECL(char, tmp)[17];
  342.                             DECL(sword_t, value);
  343.                             value = (sword_t)_VA(args, sdword_t);
  344.                             stoa(value, tmp, base_val);
  345.                             handle_lhex(lhex, tmp);
  346.                             do_transform(
  347.                                     out0, out1, buffer, length, &total,
  348.                                     (signed long long)value, flags,
  349.                                     width, base_val, tmp
  350.                             );
  351.                             BREAK;
  352.                         }
  353.                         CASE LMOD_L: {
  354.                             DECL(char, tmp)[33];
  355.                             DECL(sdword_t, value);
  356.                             value = _VA(args, sdword_t);
  357.                             ltoa(value, tmp, base_val);
  358.                             handle_lhex(lhex, tmp);
  359.                             do_transform(
  360.                                     out0, out1, buffer, length, &total,
  361.                                     (signed long long)value, flags,
  362.                                     width, base_val, tmp
  363.                             );
  364.                             BREAK;
  365.                         }
  366.                         CASE LMOD_LL: {
  367.                             DECL(char, tmp)[65];
  368.                             DECL(sqword_t, value);
  369.                             value = _VA(args, sqword_t);
  370.                             lltoa(value, tmp, base_val);
  371.                             handle_lhex(lhex, tmp);
  372.                             do_transform(
  373.                                     out0, out1, buffer, length, &total,
  374.                                     (signed long long)value, flags,
  375.                                     width, base_val, tmp
  376.                             );
  377.                             BREAK;
  378.                         }
  379.                         CASE LMOD_NONE: {
  380.                             DECL(char, tmp)[33];
  381.                             DECL(sdword_t, value);
  382.                             value = _VA(args, sdword_t);
  383.                             itoa(value, tmp, base_val);
  384.                             handle_lhex(lhex, tmp);
  385.                             do_transform(
  386.                                     out0, out1, buffer, length, &total,
  387.                                     (signed long long)value, flags,
  388.                                     width, base_val, tmp
  389.                             );
  390.                             BREAK;
  391.                         }
  392.                     }
  393.                     BREAK;
  394.                 /* Unsigned UInteger */
  395.                 CASE 'u': CASE 'o': CASE 'b':
  396.                 CASE 'x': CASE 'X': CASE 'q':
  397.                     _IF(format[count] == 'u') {
  398.                         base_val = 10;
  399.                     } _LS _IF(format[count] == 'o') {
  400.                         base_val = 8;
  401.                     } _LS _IF(format[count] == 'b') {
  402.                         base_val = 2;
  403.                     } _LS _IF(format[count] == 'q') {
  404.                         base_val = 4;
  405.                     } _LS {
  406.                         _IF(format[count] == 'x') lhex = 1;
  407.                         base_val = 16;
  408.                     }
  409.                     _SW(lmod) {
  410.                         CASE LMOD_Z: {
  411.                             DECL(char, tmp)[33];
  412.                             DECL(size_t, value);
  413.                             value = _VA(args, size_t);
  414.                             ltoa(value, tmp, base_val);
  415.                             handle_lhex(lhex, tmp);
  416.                             do_transform(
  417.                                     out0, out1, buffer, length, &total,
  418.                                     (signed long long)value, flags,
  419.                                     width, base_val, tmp
  420.                             );
  421.                             BREAK;
  422.                         }
  423.                         CASE LMOD_J: {
  424.                             DECL(char, tmp)[65];
  425.                             DECL(uintmax_t, value);
  426.                             value = _VA(args, uintmax_t);
  427.                             lltoa(value, tmp, base_val);
  428.                             handle_lhex(lhex, tmp);
  429.                             do_transform(
  430.                                     out0, out1, buffer, length, &total,
  431.                                     (signed long long)value, flags,
  432.                                     width, base_val, tmp
  433.                             );
  434.                             BREAK;
  435.                         }
  436.                         CASE LMOD_HH: {
  437.                             DECL(char, tmp)[9];
  438.                             DECL(byte_t, value);
  439.                             value = (byte_t)_VA(args, dword_t);
  440.                             ctoa(value, tmp, base_val);
  441.                             handle_lhex(lhex, tmp);
  442.                             do_transform(
  443.                                     out0, out1, buffer, length, &total,
  444.                                     (signed long long)value, flags,
  445.                                     width, base_val, tmp
  446.                             );
  447.                             BREAK;
  448.                         }
  449.                         CASE LMOD_H: {
  450.                             DECL(char, tmp)[17];
  451.                             DECL(word_t, value);
  452.                             value = (word_t)_VA(args, dword_t);
  453.                             stoa(value, tmp, base_val);
  454.                             handle_lhex(lhex, tmp);
  455.                             do_transform(
  456.                                     out0, out1, buffer, length, &total,
  457.                                     (signed long long)value, flags,
  458.                                     width, base_val, tmp
  459.                             );
  460.                             BREAK;
  461.                         }
  462.                         CASE LMOD_L: {
  463.                             DECL(char, tmp)[33];
  464.                             DECL(dword_t, value);
  465.                             value = _VA(args, dword_t);
  466.                             ltoa(value, tmp, base_val);
  467.                             handle_lhex(lhex, tmp);
  468.                             do_transform(
  469.                                     out0, out1, buffer, length, &total,
  470.                                     (signed long long)value, flags,
  471.                                     width, base_val, tmp
  472.                             );
  473.                             BREAK;
  474.                         }
  475.                         CASE LMOD_LL: {
  476.                             DECL(char, tmp)[65];
  477.                             DECL(qword_t, value);
  478.                             value = _VA(args, qword_t);
  479.                             lltoa(value, tmp, base_val);
  480.                             handle_lhex(lhex, tmp);
  481.                             do_transform(
  482.                                     out0, out1, buffer, length, &total,
  483.                                     (signed long long)value, flags,
  484.                                     width, base_val, tmp
  485.                             );
  486.                             BREAK;
  487.                         }
  488.                         CASE LMOD_NONE: {
  489.                             DECL(char, tmp)[33];
  490.                             DECL(dword_t, value);
  491.                             value = _VA(args, dword_t);
  492.                             itoa(value, tmp, base_val);
  493.                             handle_lhex(lhex, tmp);
  494.                             do_transform(
  495.                                     out0, out1, buffer, length, &total,
  496.                                     (signed long long)value, flags,
  497.                                     width, base_val, tmp
  498.                             );
  499.                             BREAK;
  500.                         }
  501.                     }
  502.                     BREAK;
  503.                 /* Single Character */
  504.                 CASE 'c': {
  505.                     DECL(byte_t, value);
  506.                     value = (byte_t)_VA(args, dword_t);
  507.                     total += out0(buffer, value);
  508.                     BREAK;
  509.                 }
  510.                 /* String of Chars */
  511.                 CASE 's': {
  512.                     DECL(_STR, value) = _VA(args, _STR);
  513.                     //DECL(value_t, remain) = total - length;
  514.                     //_IF(remain >= strlen(value)) value[remain] = ZERO;
  515.                     total += out1(buffer, value);
  516.                     BREAK;
  517.                 }
  518.                 /* Pointer Address */
  519.                 CASE 'p': {
  520.                     DECL(char, tmp)[33];
  521.                     DECL(dword_t, pvalue);
  522.                     pvalue = (dword_t)_VA(args, _G);
  523.                     pvalue = pvalue;
  524.                     ltoa(pvalue, tmp, 16);
  525.                     handle_lhex(lhex, tmp);
  526.                     total += out1(buffer, tmp);
  527.                     BREAK;
  528.                 }
  529.                 /* Default Fallback */
  530.                 DEFT: {
  531.                     DECL(byte_t, value);
  532.                     value = (byte_t)_VA(args, dword_t);
  533.                     total += out0(buffer, value);
  534.                     BREAK;
  535.                 }
  536.             }
  537.         } _LS {
  538.             total += out0(buffer, format[count]);
  539.         }
  540.     }
  541.     _IF(term) total += out0(buffer, ZERO);
  542.     _FRET total;
  543. }
  544.  
  545. DECL(pchar_t, printf)(
  546.         DECL(CONST _STR, format),
  547.         VARGS
  548.         ) {
  549.     DECL(pchar_t, val);
  550.     DECL(va_list, list);
  551.     _VS(list, format);
  552.     val = vprintf(format, list);
  553.     _VE(list);
  554.     _FRET val;
  555. }
  556.  
  557. DECL(pchar_t, sprintf)(
  558.         DECL(_STR, str),
  559.         DECL(CONST _STR, format),
  560.         VARGS
  561.         ) {
  562.     DECL(pchar_t, val);
  563.     DECL(va_list, list);
  564.     _VS(list, format);
  565.     val = vsprintf(str, format, list);
  566.     _VE(list);
  567.     _FRET val;
  568. }
  569.  
  570. DECL(pchar_t, snprintf)(
  571.         DECL(_STR, str),
  572.         DECL(length_t, ct),
  573.         DECL(CONST _STR, format),
  574.         VARGS
  575.         ) {
  576.     DECL(pchar_t, val);
  577.     DECL(va_list, list);
  578.     _VS(list, format);
  579.     val = vsnprintf(str, ct, format, list);
  580.     _VE(list);
  581.     _FRET val;
  582. }
  583.  
  584. HIDDEN
  585. DECL(pchar_t, vwrite0)(
  586.         DECL(_STR, buffer),
  587.         DECL(pchar_t, character)
  588.         ) {
  589.     buffer = buffer;
  590.     _FRET putchar(character);
  591. }
  592.  
  593. HIDDEN
  594. DECL(pchar_t, vwrite1)(
  595.         DECL(_STR, buffer),
  596.         DECL(CONST _STR, str)
  597.         ) {
  598.     buffer = buffer;
  599.     _FRET puts(str);
  600. }
  601.  
  602. DECL(pchar_t, vprintf)(
  603.         DECL(CONST _STR, format),
  604.         DECL(va_list, args)
  605.         ) {
  606.     _FRET do_printf(
  607.             vwrite0, vwrite1,
  608.             ZERO, INT32_MAX,
  609.             format, args,
  610.             ZERO
  611.     );
  612. }
  613.  
  614. HIDDEN
  615. DECL(pchar_t, vswrite0)(
  616.         DECL(_STR, buffer),
  617.         DECL(pchar_t, character)
  618.         ) {
  619.     *(byte_t *)buffer = (byte_t)character;
  620.     _FRET 1;
  621. }
  622.  
  623. HIDDEN
  624. DECL(pchar_t, vswrite1)(
  625.         DECL(_STR, buffer),
  626.         DECL(CONST _STR, str)
  627.         ) {
  628.     _FI(count, ZERO, UINT32_MAX) {
  629.         _IF(!str[count]) _FRET count;
  630.         vswrite0(&buffer[count], str[count]);
  631.     }
  632.     _FRET ZERO;
  633. }
  634.  
  635. DECL(pchar_t, vsprintf)(
  636.         DECL(_STR, str),
  637.         DECL(CONST _STR, format),
  638.         DECL(va_list, args)
  639.         ) {
  640.     _FRET do_printf(
  641.             vswrite0, vswrite1,
  642.             str, INT32_MAX,
  643.             format, args,
  644.             !ZERO
  645.     );
  646. }
  647.  
  648. DECL(pchar_t, vsnprintf)(
  649.         DECL(_STR, str),
  650.         DECL(length_t, ct),
  651.         DECL(CONST _STR, format),
  652.         DECL(va_list, args)
  653.         ) {
  654.     _FRET do_printf(
  655.             vswrite0, vswrite1,
  656.             str, ct, format, args,
  657.             !ZERO
  658.     );
  659. }
Advertisement
Add Comment
Please, Sign In to add comment