alt_printf 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,6 @@
1
+ #ifndef ARGTYPE_H_
2
+ #define ARGTYPE_H_
3
+ enum arg_type { FMul, FTern, FAlign, FInt, FChar, FDouble, FString, FRaw, FNone,
4
+ FEnd };
5
+ enum align { Left, Right, Center };
6
+ #endif
@@ -0,0 +1 @@
1
+
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- require 'mkmf'
3
2
 
4
- create_header
5
- create_makefile('alt_printf')
3
+ require_relative 'extconf_helper'
4
+ ExtconfHelper.setup
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative 'extconf_helper'
4
+ ExtconfHelper.setup('debug')
@@ -1,9 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- require 'mkmf'
3
2
 
4
- base_dir = File.join(__dir__, '../../../')
5
- find_header('altprintf.h', File.join(base_dir, 'src'))
6
- $objs = Dir[File.join(base_dir, 'target/release/*.o')] + ['alt_printf.o']
7
-
8
- create_header
9
- create_makefile('alt_printf')
3
+ require_relative 'extconf_helper'
4
+ ExtconfHelper.setup('dev')
@@ -0,0 +1,35 @@
1
+ require 'mkmf'
2
+
3
+ module ExtconfHelper
4
+ BASE_DIR = File.join(__dir__, '../../../')
5
+
6
+ module_function
7
+
8
+ def dev_header
9
+ find_header('altprintf.h', File.join(BASE_DIR, 'src'))
10
+ end
11
+
12
+ def dev_objs(folder = 'release')
13
+ $objs = Dir[File.join(BASE_DIR, "target/#{folder}/*.o")] + ['alt_printf.o']
14
+ end
15
+
16
+ def setup(mode = 'release')
17
+ puts "extconf setting up #{mode}"
18
+ case mode
19
+ when 'release'
20
+ # do nothing
21
+ when 'dev'
22
+ dev_header
23
+ dev_objs('release')
24
+ when 'debug'
25
+ dev_header
26
+ $defs.push("-DDEBUG")
27
+ dev_objs('debug')
28
+ else
29
+ raise(ArgumentError, "invalid mode #{mode}")
30
+ end
31
+
32
+ create_header
33
+ create_makefile('alt_printf')
34
+ end
35
+ end
@@ -0,0 +1,174 @@
1
+ #include "fmt.h"
2
+
3
+ #define BUFNUM 25
4
+
5
+ void fmt_mul(struct strbuf *sb, struct fmte *f) {
6
+ long int *i = f->value;
7
+ if (f->parenarg_start == NULL) {
8
+ strbuf_pad(sb, f->chararg, *i);
9
+ } else {
10
+ for (int j=0; j<*i; j++) {
11
+ strbuf_append_str(sb, f->parenarg_start, -f->parenarg_len);
12
+ }
13
+ }
14
+ }
15
+
16
+ void fmt_tern(struct strbuf *sb, struct fmte *f) {
17
+ if (f->parenarg_start == NULL) return;
18
+
19
+ long int *b = f->value;
20
+ int first_half = 1;
21
+ wchar_t sep = f->chararg;
22
+ wchar_t *p = f->parenarg_start;
23
+ for (;p<=f->parenarg_end;p++) {
24
+ LOG("*p: %lc, first half? %d, bool: %ld, sep: %lc\n", (wint_t)*p, first_half, *b, (wint_t)sep);
25
+ if (*p == sep) first_half = 0;
26
+ else if (*b && first_half) strbuf_append_char(sb, p);
27
+ else if (!*b && !first_half) strbuf_append_char(sb, p);
28
+ }
29
+ }
30
+
31
+ void fmt_raw(struct strbuf *sb, struct fmte *f) {
32
+ strbuf_append_str(sb, f->parenarg_start, -1 * f->parenarg_len);
33
+ }
34
+
35
+ void fmt_string(struct strbuf *sb, struct fmte *f) {
36
+ int prec = f->prec == -1 ? 100000000 : f->prec;
37
+ strbuf_append_str(sb, f->value, prec);
38
+ }
39
+
40
+ void fmt_char(struct strbuf *sb, struct fmte *f) {
41
+ strbuf_append_char(sb, f->value);
42
+ }
43
+
44
+ void fmt_int(struct strbuf *sb, struct fmte *f) {
45
+ strbuf_append_int(sb, f->value);
46
+ }
47
+
48
+ void fmt_double(struct strbuf *sb, struct fmte *f) {
49
+ int prec = f->prec == -1 ? 3 : f->prec;
50
+ strbuf_append_double(sb, f->value, prec);
51
+ }
52
+
53
+ void fmt(struct strbuf *sb, struct fmte *f, void (*fmtr)(struct strbuf *, struct fmte *)) {
54
+ struct strbuf *tmp = strbuf_new();
55
+ fmtr(tmp, f);
56
+
57
+ if (tmp->len == 0) {
58
+ strbuf_destroy(tmp);
59
+ return;
60
+ };
61
+
62
+ int pad = f->pad - tmp->width;
63
+
64
+ if (pad > 0) {
65
+ LOG("padding: %d\n", pad);
66
+ switch(f->align) {
67
+ case Right:
68
+ strbuf_append_strbuf(sb, tmp);
69
+ strbuf_pad(sb, f->padchar, pad);
70
+ break;
71
+ case Left:
72
+ strbuf_pad(sb, f->padchar, pad);
73
+ strbuf_append_strbuf(sb, tmp);
74
+ break;
75
+ case Center:
76
+ strbuf_pad(sb, f->padchar, pad/2);
77
+ strbuf_append_strbuf(sb, tmp);
78
+ strbuf_pad(sb, f->padchar, pad/2 + pad%2);
79
+ break;
80
+ }
81
+ } else {
82
+ strbuf_append_strbuf(sb, tmp);
83
+ }
84
+
85
+ strbuf_destroy(tmp);
86
+ }
87
+
88
+ wchar_t *assemble_fmt(struct fmte *head) {
89
+ struct fmte *f = head;
90
+ struct strbuf *bufs[BUFNUM];
91
+ struct fmte *splits[BUFNUM];
92
+ size_t buf = 0, i;
93
+ size_t w, tw, rw;
94
+ wchar_t *final;
95
+ void (*fmtr)(struct strbuf *, struct fmte *) = NULL;
96
+ int loop = 1;
97
+
98
+ bufs[buf] = strbuf_new();
99
+
100
+ LOG("assembling elements\n");
101
+ while (loop) {
102
+ switch (f->type) {
103
+ case FMul:
104
+ fmtr = fmt_mul;
105
+ break;
106
+ case FTern:
107
+ fmtr = fmt_tern;
108
+ break;
109
+ case FInt:
110
+ fmtr = fmt_int;
111
+ break;
112
+ case FChar:
113
+ fmtr = fmt_char;
114
+ break;
115
+ case FDouble:
116
+ fmtr = fmt_double;
117
+ break;
118
+ case FString:
119
+ fmtr = fmt_string;
120
+ break;
121
+ case FRaw:
122
+ fmtr = fmt_raw;
123
+ break;
124
+
125
+ case FAlign:
126
+ buf++;
127
+ splits[buf] = f;
128
+ bufs[buf] = strbuf_new();
129
+ fmtr = NULL;
130
+ break;
131
+ case FEnd:
132
+ loop = 0;
133
+ fmtr = NULL;
134
+ break;
135
+ case FNone:
136
+ fmtr = NULL;
137
+ break;
138
+ }
139
+
140
+ if (fmtr != NULL) fmt(bufs[buf], f, fmtr);
141
+ f = f->next;
142
+ }
143
+
144
+ // Assemble splits
145
+ LOG("assembling %d splits\n", buf);
146
+ tw = bufs[0]->width;
147
+ for (i = 1; i <= buf; i++) {
148
+ rw = *(long *)splits[i]->value;
149
+
150
+ if (tw > rw) {
151
+ LOG("trimming first half to width\n");
152
+ strbuf_destroy(bufs[i]);
153
+ bufs[i] = bufs[0];
154
+ bufs[0] = strbuf_new();
155
+ strbuf_appendw_strbuf(bufs[0], bufs[i], rw);
156
+ } else {
157
+ if (rw > bufs[i]->width + tw) {
158
+ w = rw - (bufs[i]->width + tw);
159
+ LOG("padding %d\n", w);
160
+ strbuf_pad(bufs[0], splits[i]->chararg, w);
161
+ strbuf_append_strbuf(bufs[0], bufs[i]);
162
+ } else {
163
+ LOG("%d %d %d\n", w, rw, tw);
164
+ strbuf_appendw_strbuf(bufs[0], bufs[i], rw - tw);
165
+ }
166
+ }
167
+
168
+ tw = rw;
169
+ }
170
+
171
+ final = strbuf_cstr(bufs[0]);
172
+ for (i = 0; i <= buf; i++) strbuf_destroy(bufs[i]);
173
+ return final;
174
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef FMT_H_
2
+ #define FMT_H_
3
+ #include "strbuf.h"
4
+ #include "fmte.h"
5
+ #include "log.h"
6
+
7
+ wchar_t *assemble_fmt(struct fmte *);
8
+ #endif
@@ -0,0 +1,92 @@
1
+ #include "fmte.h"
2
+
3
+ struct fmte *fmte_ini() {
4
+ struct fmte *f = malloc(sizeof(struct fmte));
5
+
6
+ f->parenarg_start = NULL;
7
+ f->parenarg_end = NULL;
8
+ f->parenarg_len = 0;
9
+
10
+ f->anglearg_start = NULL;
11
+ f->anglearg_end = NULL;
12
+ f->anglearg_len = 0;
13
+
14
+ f->chararg = L' ';
15
+ f->padchar = L' ';
16
+ f->type = FNone;
17
+ f->align = Right;
18
+ f->prec = -1;
19
+ f->pad = 0;
20
+ f->value = NULL;
21
+
22
+ f->next = NULL;
23
+
24
+ return f;
25
+ }
26
+
27
+ void fmte_push(struct fmte *a, struct fmte *b) {
28
+ if (a == b) return; // refuse to create an infinite loop
29
+
30
+ while (a->next != NULL) a = a->next;
31
+
32
+ a->next = b;
33
+ }
34
+
35
+ void fmte_destroy(struct fmte *f) {
36
+ struct fmte *j;
37
+ while (f != NULL) {
38
+ j = f->next;
39
+ free(f->value);
40
+ free(f);
41
+ f = j;
42
+ }
43
+ }
44
+
45
+ void fmte_inspect(struct fmte *f) {
46
+ wchar_t *parenarg = calloc(f->parenarg_len + 1, sizeof(wchar_t));
47
+ wchar_t *anglearg = calloc(f->anglearg_len + 1, sizeof(wchar_t));
48
+ size_t i;
49
+
50
+ for (i=0;i<f->parenarg_len;i++) parenarg[i] = f->parenarg_start[i];
51
+ for (i=0;i<f->anglearg_len;i++) anglearg[i] = f->anglearg_start[i];
52
+
53
+ printf(
54
+ "Format@%p {\n\
55
+ parenarg_start: %p,\n\
56
+ parenarg_end: %p,\n\
57
+ parenarg_len: %d,\n\
58
+ (parenarg): %ls,\n\
59
+ anglearg_start: %p,\n\
60
+ anglearg_end: %p,\n\
61
+ anglearg_len: %d,\n\
62
+ (anglearg): %ls,\n\
63
+ chararg: %lc,\n\
64
+ padchar: %lc,\n\
65
+ type: %d,\n\
66
+ align: %d,\n\
67
+ prec: %ld,\n\
68
+ pad: %ld,\n\
69
+ value: %p,\n\
70
+ next: %p\n\
71
+ }\n",
72
+ f,
73
+ f->parenarg_start,
74
+ f->parenarg_end,
75
+ f->parenarg_len,
76
+ parenarg,
77
+ f->anglearg_start,
78
+ f->anglearg_end,
79
+ f->anglearg_len,
80
+ anglearg,
81
+ f->chararg,
82
+ f->padchar,
83
+ f->type,
84
+ f->align,
85
+ f->prec,
86
+ f->pad,
87
+ f->value,
88
+ f->next);
89
+
90
+ free(parenarg);
91
+ free(anglearg);
92
+ }
@@ -0,0 +1,37 @@
1
+ #ifndef FMTE_H_
2
+ #define FMTE_H_
3
+ #include <wchar.h>
4
+ #include <stdlib.h>
5
+ #include <stdio.h>
6
+ #include "enums.h"
7
+ #include "log.h"
8
+
9
+ struct fmte {
10
+ wchar_t *parenarg_start;
11
+ wchar_t *parenarg_end;
12
+ size_t parenarg_len;
13
+
14
+ wchar_t *anglearg_start;
15
+ wchar_t *anglearg_end;
16
+ size_t anglearg_len;
17
+
18
+ wint_t chararg;
19
+
20
+ wint_t padchar;
21
+
22
+ enum arg_type type;
23
+ enum align align;
24
+
25
+ long prec;
26
+ long pad;
27
+
28
+ void *value;
29
+
30
+ struct fmte *next;
31
+ };
32
+
33
+ struct fmte *fmte_ini();
34
+ void fmte_inspect(struct fmte *);
35
+ void fmte_push(struct fmte *, struct fmte *);
36
+ void fmte_destroy(struct fmte *);
37
+ #endif
data/ext/alt_printf/log.h CHANGED
@@ -2,10 +2,11 @@
2
2
  #define LOG_H
3
3
 
4
4
  #ifdef DEBUG
5
- #define LOG(...) printf("%s[%d] - ", __FILE__, __LINE__);printf(__VA_ARGS__);
5
+ #define LOG(...) printf("%s:%d [\e[35m%s\e[0m] ", __FILE__, __LINE__, __func__);printf(__VA_ARGS__);
6
6
  #define FLOG(msg, ...) fprintf(stderr, "%s[%d] - "msg, __FILE__, __LINE__ __VA_OPT__(,) __VA_ARGS__)
7
7
  #else
8
8
  #define LOG(msg, ...)
9
9
  #define FLOG(msg, ...)
10
10
  #endif
11
+
11
12
  #endif
@@ -0,0 +1,125 @@
1
+ #include "parsef.h"
2
+
3
+ #define EOS L'\0'
4
+
5
+ wchar_t *altprintf_pct = L"%";
6
+
7
+ struct fmte *parsef(wchar_t **fmt) {
8
+ wchar_t *w_c;
9
+ wchar_t **w_a = &w_c;
10
+ struct fmte *f = fmte_ini();
11
+ long *l_a = &f->pad;
12
+
13
+ LOG("processing %ld (%lc)\n", **fmt, (wint_t)**fmt);
14
+
15
+ if (**fmt != FS_START) {
16
+ if (**fmt == EOS) {
17
+ f->type = FEnd;
18
+ goto return_format;
19
+ }
20
+
21
+ LOG("building raw format\n");
22
+ f->type = FRaw;
23
+
24
+ f->parenarg_start = *fmt;
25
+ LOG("scanning long arg\n");
26
+ get_longarg(fmt, &f->parenarg_end, FS_START, &f->parenarg_len);
27
+
28
+ f->parenarg_end++;
29
+ f->parenarg_len++;
30
+ (*fmt)--;
31
+
32
+ goto return_format;
33
+ } else {
34
+ LOG("building format\n");
35
+ (*fmt)++;
36
+ }
37
+
38
+ for (;**fmt != L'\0';(*fmt)++) {
39
+ LOG("scanned char '%lc'\n", (wint_t)(**fmt));
40
+ switch (**fmt) {
41
+ case FS_A_CHARARG:
42
+ (*fmt)++;
43
+ f->chararg = **fmt;
44
+ break;
45
+ case FS_A_ANGLEARG_S:
46
+ f->anglearg_start = *fmt + 1;
47
+ get_longarg(fmt, &f->anglearg_end, FS_A_ANGLEARG_E, &f->anglearg_len);
48
+ break;
49
+ case FS_A_PARENARG_S:
50
+ f->parenarg_start = *fmt + 1;
51
+ get_longarg(fmt, &f->parenarg_end, FS_A_PARENARG_E, &f->parenarg_len);
52
+ break;
53
+ case FS_A_LALIGN:
54
+ f->align = Left;
55
+ break;
56
+ case FS_A_CALIGN:
57
+ f->align = Center;
58
+ break;
59
+ case FS_A_SPAD:
60
+ f->padchar = FS_A_SPAD;
61
+ break;
62
+ case FS_A_ZPAD:
63
+ f->padchar = '0';
64
+ break;
65
+ case FS_A_PREC:
66
+ l_a = &f->prec;
67
+ break;
68
+ case '1': case '2': case '3': case '4': case '5':
69
+ case '6': case '7': case '8': case '9':
70
+ LOG("l_a: %p %ld\n", l_a, *l_a);
71
+ *l_a = wcstol(*fmt, w_a, 10);
72
+ *fmt = *w_a - 1;
73
+ break;
74
+ // Psuedo-type
75
+ case FS_START:
76
+ f->type = FRaw;
77
+ f->parenarg_start = &altprintf_pct[0];
78
+ f->parenarg_end = &altprintf_pct[1];
79
+ f->parenarg_len = 1;
80
+ goto return_format;
81
+ // Types
82
+ case FS_T_STRING:
83
+ f->type = FString;
84
+ goto return_format;
85
+ case FS_T_MUL:
86
+ f->type = FMul;
87
+ goto return_format;
88
+ case FS_T_TERN:
89
+ f->type = FTern;
90
+ goto return_format;
91
+ case FS_T_ALIGN:
92
+ f->type = FAlign;
93
+ goto return_format;
94
+ case FS_T_INT:
95
+ f->type = FInt;
96
+ goto return_format;
97
+ case FS_T_CHAR:
98
+ f->type = FChar;
99
+ goto return_format;
100
+ case FS_T_DOUBLE:
101
+ f->type = FDouble;
102
+ goto return_format;
103
+ default:
104
+ f->type = FRaw;
105
+ }
106
+ }
107
+
108
+ f->type = FEnd;
109
+ return_format:
110
+ (*fmt)++;
111
+ return f;
112
+ }
113
+
114
+ void get_longarg(wchar_t **s, wchar_t **e, wchar_t stop, size_t *size) {
115
+ *size = 0;
116
+
117
+ while (**s != EOS && **s != stop) {
118
+ LOG("checking (%lc)\n", (wint_t)**s);
119
+ (*s)++;
120
+ (*size)++;
121
+ }
122
+
123
+ (*size)--;
124
+ if (*size > 0) *e = *s - 1;
125
+ }