alt_printf 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+ }