スタック、キュー
@@ -3,12 +3,13 @@ | ||
3 | 3 | libnpl.a: npl.o object.o stream.o str.o mbstr.o type.o sbuf.o \ |
4 | 4 | array.o buf.o chunk.o val.o var.o tuple.o func.o \ |
5 | 5 | member.o state.o stack.o def.o block.o token.o tq.o q.o \ |
6 | -pointer.o | |
6 | +pointer.o vq.o queue.o s.o vs.o | |
7 | 7 | ar rcs libnpl.a npl.o object.o stream.o str.o \ |
8 | 8 | mbstr.o type.o sbuf.o array.o buf.o \ |
9 | 9 | chunk.o val.o var.o tuple.o \ |
10 | 10 | func.o member.o state.o stack.o \ |
11 | - def.o block.o token.o tq.o q.o pointer.o | |
11 | + def.o block.o token.o tq.o q.o pointer.o \ | |
12 | + vq.o queue.o s.o vs.o | |
12 | 13 | |
13 | 14 | npl.o: npl.c npl.h global.h |
14 | 15 | gcc -c npl.c |
@@ -79,6 +80,18 @@ | ||
79 | 80 | pointer.o: pointer.c npl.h global.h |
80 | 81 | gcc -c pointer.c |
81 | 82 | |
83 | +vq.o: vq.c npl.h global.h | |
84 | + gcc -c vq.c | |
85 | + | |
86 | +queue.o: queue.c npl.h global.h | |
87 | + gcc -c queue.c | |
88 | + | |
89 | +s.o: s.c npl.h global.h | |
90 | + gcc -c s.c | |
91 | + | |
92 | +vs.o: vs.c npl.h global.h | |
93 | + gcc -c vs.c | |
94 | + | |
82 | 95 | clean: |
83 | 96 | rm -f *.o |
84 | 97 | rm -f libnpl.a |
@@ -41,7 +41,7 @@ | ||
41 | 41 | return 1; // error |
42 | 42 | } |
43 | 43 | |
44 | - v = npl_array_ref(a, i); | |
44 | + v = npl_array_ret(a, i); | |
45 | 45 | if (val == NULL) |
46 | 46 | npl_val_set_null(v); |
47 | 47 | else |
@@ -64,7 +64,7 @@ | ||
64 | 64 | return 1; // error |
65 | 65 | } |
66 | 66 | |
67 | - v = npl_array_ref(a, i); | |
67 | + v = npl_array_ret(a, i); | |
68 | 68 | if (val_r != NULL) |
69 | 69 | npl_val_copy(val_r, v); |
70 | 70 |
@@ -71,10 +71,9 @@ | ||
71 | 71 | return 0; |
72 | 72 | } |
73 | 73 | |
74 | - | |
75 | 74 | // i 番目の val の参照を返す。 |
76 | 75 | // 返された参照を npl_val_end() で終了してはならない。 |
77 | -npl_val_t* npl_array_ref(npl_array_t *a, size_t i) | |
76 | +npl_val_t* npl_array_ret(npl_array_t *a, size_t i) | |
78 | 77 | { |
79 | 78 | assert(a); |
80 | 79 |
@@ -33,7 +33,7 @@ | ||
33 | 33 | } |
34 | 34 | |
35 | 35 | // バッファ先頭へのポインタを返す |
36 | -void* npl_buf_buf(npl_buf_t *buf) | |
36 | +void* npl_buf_ret(npl_buf_t *buf) | |
37 | 37 | { |
38 | 38 | assert(buf); |
39 | 39 | return buf->buf; |
@@ -53,7 +53,7 @@ | ||
53 | 53 | } |
54 | 54 | |
55 | 55 | // データ領域へのポインタを返す |
56 | -void* npl_chunk_chunk(npl_chunk_t *c) | |
56 | +void* npl_chunk_ret(npl_chunk_t *c) | |
57 | 57 | { |
58 | 58 | assert(c); |
59 | 59 | return c->chunk; |
@@ -51,7 +51,7 @@ | ||
51 | 51 | |
52 | 52 | // マルチバイト文字列オブジェクトの |
53 | 53 | // 内容を返す。 |
54 | -char* npl_mbstr_get(npl_mbstr_t *str) | |
54 | +char* npl_mbstr_ret(npl_mbstr_t *str) | |
55 | 55 | { |
56 | 56 | assert(str); |
57 | 57 | return str->chunk.chunk; |
@@ -24,8 +24,12 @@ | ||
24 | 24 | #define NPL_FUNC(x) _NPL_CAST(npl_func_t, x, npl_func_type) |
25 | 25 | #define NPL_MEMBER(x) _NPL_CAST(npl_member_t, x, npl_member_type) |
26 | 26 | #define NPL_STATE(x) _NPL_CAST(npl_state_t, x, npl_state_type) |
27 | +#define NPL_S(x) _NPL_CAST(npl_s_t, x, npl_s_type) | |
28 | +#define NPL_VS(x) _NPL_CAST(npl_vs_t, x, npl_vs_type) | |
27 | 29 | #define NPL_STACK(x) _NPL_CAST(npl_stack_t, x, npl_stack_type) |
28 | 30 | #define NPL_Q(x) _NPL_CAST(npl_q_t, x, npl_q_type) |
31 | +#define NPL_VQ(x) _NPL_CAST(npl_vq_t, x, npl_vq_type) | |
32 | +#define NPL_QUEUE(x) _NPL_CAST(npl_queue_t, x, npl_queue_type) | |
29 | 33 | #define NPL_TQ(x) _NPL_CAST(npl_tq_t, x, npl_tq_type) |
30 | 34 | #define NPL_STREAM(x) _NPL_CAST(npl_stream_t, x, npl_stream_type) |
31 | 35 |
@@ -52,8 +56,12 @@ | ||
52 | 56 | typedef struct npl_func_t npl_func_t; |
53 | 57 | typedef struct npl_member_t npl_member_t; |
54 | 58 | typedef struct npl_state_t npl_state_t; |
59 | +typedef struct npl_s_t npl_s_t; | |
60 | +typedef struct npl_vs_t npl_vs_t; | |
55 | 61 | typedef struct npl_stack_t npl_stack_t; |
56 | 62 | typedef struct npl_q_t npl_q_t; |
63 | +typedef struct npl_vq_t npl_vq_t; | |
64 | +typedef struct npl_queue_t npl_queue_t; | |
57 | 65 | typedef struct npl_tq_t npl_tq_t; |
58 | 66 | typedef struct npl_stream_t npl_stream_t; |
59 | 67 |
@@ -88,8 +96,12 @@ | ||
88 | 96 | extern npl_type_t _npl_func_type; |
89 | 97 | extern npl_type_t _npl_member_type; |
90 | 98 | extern npl_type_t _npl_state_type; |
99 | +extern npl_type_t _npl_s_type; | |
100 | +extern npl_type_t _npl_vs_type; | |
91 | 101 | extern npl_type_t _npl_stack_type; |
92 | 102 | extern npl_type_t _npl_q_type; |
103 | +extern npl_type_t _npl_vq_type; | |
104 | +extern npl_type_t _npl_queue_type; | |
93 | 105 | extern npl_type_t _npl_tq_type; |
94 | 106 | extern npl_type_t _npl_stream_type; |
95 | 107 |
@@ -108,8 +120,12 @@ | ||
108 | 120 | extern npl_type_t *npl_func_type; |
109 | 121 | extern npl_type_t *npl_member_type; |
110 | 122 | extern npl_type_t *npl_state_type; |
123 | +extern npl_type_t *npl_s_type; | |
124 | +extern npl_type_t *npl_vs_type; | |
111 | 125 | extern npl_type_t *npl_stack_type; |
112 | 126 | extern npl_type_t *npl_q_type; |
127 | +extern npl_type_t *npl_vq_type; | |
128 | +extern npl_type_t *npl_queue_type; | |
113 | 129 | extern npl_type_t *npl_tq_type; |
114 | 130 | extern npl_type_t *npl_stream_type; |
115 | 131 |
@@ -193,8 +209,12 @@ | ||
193 | 209 | NPL_VT_FUNC, |
194 | 210 | NPL_VT_MEMBER, |
195 | 211 | NPL_VT_STATE, |
212 | + NPL_VT_S, | |
213 | + NPL_VT_VS, | |
196 | 214 | NPL_VT_STACK, |
197 | 215 | NPL_VT_Q, |
216 | + NPL_VT_VQ, | |
217 | + NPL_VT_QUEUE, | |
198 | 218 | NPL_VT_TQ, |
199 | 219 | NPL_VT_STREAM, |
200 | 220 | }; |
@@ -232,8 +252,12 @@ | ||
232 | 252 | npl_func_t *func; |
233 | 253 | npl_member_t *member; |
234 | 254 | npl_state_t *state; |
255 | + npl_s_t *s; | |
256 | + npl_vs_t *vs; | |
235 | 257 | npl_stack_t *stack; |
236 | 258 | npl_q_t *q; |
259 | + npl_vq_t *vq; | |
260 | + npl_queue_t *queue; | |
237 | 261 | npl_tq_t *tq; |
238 | 262 | npl_stream_t *stream; |
239 | 263 | }; |
@@ -277,8 +301,12 @@ | ||
277 | 301 | void npl_val_set_func(npl_val_t *val, npl_func_t *func); |
278 | 302 | void npl_val_set_member(npl_val_t *val, npl_member_t *member); |
279 | 303 | void npl_val_set_state(npl_val_t *val, npl_state_t *state); |
304 | +void npl_val_set_s(npl_val_t *val, npl_s_t *s); | |
305 | +void npl_val_set_vs(npl_val_t *val, npl_vs_t *vs); | |
280 | 306 | void npl_val_set_stack(npl_val_t *val, npl_stack_t *stack); |
281 | 307 | void npl_val_set_q(npl_val_t *val, npl_q_t *q); |
308 | +void npl_val_set_vq(npl_val_t *val, npl_vq_t *vq); | |
309 | +void npl_val_set_queue(npl_val_t *val, npl_queue_t *queue); | |
282 | 310 | void npl_val_set_tq(npl_val_t *val, npl_tq_t *tq); |
283 | 311 | void npl_val_set_stream(npl_val_t *val, npl_stream_t *stream); |
284 | 312 |
@@ -290,6 +318,7 @@ | ||
290 | 318 | }; |
291 | 319 | |
292 | 320 | npl_object_t* npl_object_alloc(npl_type_t *type); |
321 | +npl_object_t* npl_object_new(void); | |
293 | 322 | void npl_object_ref(npl_object_t *object); |
294 | 323 | void npl_object_unref(npl_object_t *object); |
295 | 324 |
@@ -345,7 +374,7 @@ | ||
345 | 374 | int npl_buf_init(npl_buf_t *buf, size_t bytes); |
346 | 375 | npl_buf_t* npl_buf_new(size_t bytes); |
347 | 376 | size_t npl_buf_bytes(npl_buf_t *buf); |
348 | -void* npl_buf_buf(npl_buf_t *buf); | |
377 | +void* npl_buf_ret(npl_buf_t *buf); | |
349 | 378 | void npl_buf_clear(npl_buf_t *buf); |
350 | 379 | int npl_buf_resize(npl_buf_t *buf, size_t bytes); |
351 | 380 | int npl_buf_expand(npl_buf_t *buf, size_t bytes); |
@@ -367,7 +396,7 @@ | ||
367 | 396 | npl_array_t* npl_array_new(size_t len); |
368 | 397 | int npl_array_set(npl_array_t *a, size_t i, npl_val_t *val); |
369 | 398 | int npl_array_get(npl_array_t *a, size_t i, npl_val_t *val_r); |
370 | -npl_val_t* npl_array_ref(npl_array_t *a, size_t i); | |
399 | +npl_val_t* npl_array_ret(npl_array_t *a, size_t i); | |
371 | 400 | int npl_array_add(npl_array_t *a, npl_val_t *val); |
372 | 401 | size_t npl_array_len(npl_array_t *a); |
373 | 402 | int npl_array_resize(npl_array_t *a, size_t len); |
@@ -384,7 +413,7 @@ | ||
384 | 413 | npl_sbuf_t* npl_sbuf_new(void); |
385 | 414 | int npl_sbuf_add(npl_sbuf_t *sb, const wchar_t *s); |
386 | 415 | size_t npl_sbuf_size(npl_sbuf_t *sb); |
387 | -wchar_t* npl_sbuf_buf(npl_sbuf_t *sb); | |
416 | +wchar_t* npl_sbuf_ret(npl_sbuf_t *sb); | |
388 | 417 | size_t npl_sbuf_len(npl_sbuf_t *sb); |
389 | 418 | void npl_sbuf_clear(npl_sbuf_t *sb); |
390 | 419 | npl_str_t* npl_sbuf_to_str(npl_sbuf_t *sb); |
@@ -405,7 +434,7 @@ | ||
405 | 434 | |
406 | 435 | npl_chunk_t* npl_chunk_alloc(npl_type_t *type, size_t bytes); |
407 | 436 | size_t npl_chunk_bytes(npl_chunk_t *c); |
408 | -void* npl_chunk_chunk(npl_chunk_t *c); | |
437 | +void* npl_chunk_ret(npl_chunk_t *c); | |
409 | 438 | void npl_chunk_clear(npl_chunk_t *c); |
410 | 439 | |
411 | 440 | // block class |
@@ -426,7 +455,7 @@ | ||
426 | 455 | |
427 | 456 | npl_str_t* npl_str_new(const wchar_t *s); |
428 | 457 | npl_str_t* npl_str_new_from_mbs(const char *s); |
429 | -wchar_t* npl_str_get(npl_str_t *s); | |
458 | +wchar_t* npl_str_ret(npl_str_t *s); | |
430 | 459 | |
431 | 460 | // mbstr class |
432 | 461 | // mbstr はマルチバイト文字の文字列。 |
@@ -436,7 +465,7 @@ | ||
436 | 465 | |
437 | 466 | npl_mbstr_t* npl_mbstr_new(const char *s); |
438 | 467 | npl_mbstr_t* npl_mbstr_new_from_wcs(const wchar_t *s); |
439 | -char* npl_mbstr_get(npl_mbstr_t *str); | |
468 | +char* npl_mbstr_ret(npl_mbstr_t *str); | |
440 | 469 | |
441 | 470 | // var class |
442 | 471 | struct npl_var_t { |
@@ -450,7 +479,7 @@ | ||
450 | 479 | wchar_t* npl_var_name(npl_var_t *var); |
451 | 480 | void npl_var_set(npl_var_t *var, npl_val_t *val); |
452 | 481 | void npl_var_get(npl_var_t *var, npl_val_t *val_r); |
453 | -npl_val_t* npl_var_ref(npl_var_t *var); | |
482 | +npl_val_t* npl_var_ret(npl_var_t *var); | |
454 | 483 | |
455 | 484 | // tuple class |
456 | 485 | struct npl_tuple_t { |
@@ -462,7 +491,7 @@ | ||
462 | 491 | size_t npl_tuple_len(npl_tuple_t *tuple); |
463 | 492 | void npl_tuple_set(npl_tuple_t *tuple, size_t i, npl_val_t *val); |
464 | 493 | void npl_tuple_get(npl_tuple_t *tuple, size_t i, npl_val_t *val_r); |
465 | -npl_val_t* npl_tuple_ref(npl_tuple_t *tuple, size_t i); | |
494 | +npl_val_t* npl_tuple_ret(npl_tuple_t *tuple, size_t i); | |
466 | 495 | |
467 | 496 | // func class |
468 | 497 | struct npl_func_t { |
@@ -490,26 +519,67 @@ | ||
490 | 519 | npl_stack_t *stack; |
491 | 520 | }; |
492 | 521 | |
493 | -// stack class | |
494 | -struct npl_stack_t { | |
495 | - npl_array_t array; | |
522 | +// s (Stack), 基本のスタック | |
523 | +struct npl_s_t { | |
524 | + npl_buf_t buf; | |
525 | + size_t el_size; | |
496 | 526 | size_t count; |
497 | 527 | size_t count2; |
528 | + size_t expand_bytes; | |
498 | 529 | npl_buf_t *count_stack; |
499 | 530 | size_t count_stack_pos; |
531 | + void (*cleaner)(void *data); | |
500 | 532 | }; |
501 | 533 | |
502 | -int npl_stack_init(npl_stack_t *s); | |
534 | +int npl_s_init(npl_s_t *s, size_t el_size); | |
535 | +npl_s_t* npl_s_new(size_t el_size); | |
536 | +size_t npl_s_size(npl_s_t *s); | |
537 | +size_t npl_s_count(npl_s_t *s); | |
538 | +size_t npl_s_len(npl_s_t *s); | |
539 | +int npl_s_enter(npl_s_t *s); | |
540 | +int npl_s_leave(npl_s_t *s); | |
541 | +int npl_s_is_empty(npl_s_t *s); | |
542 | +void npl_s_empty(npl_s_t *s); | |
543 | +void* npl_s_push(npl_s_t *s); | |
544 | +void* npl_s_ret(npl_s_t *s, size_t n); | |
545 | +void npl_s_remove(npl_s_t *s, size_t n); | |
546 | + | |
547 | +// vs (val stack), valのスタック | |
548 | +struct npl_vs_t { | |
549 | + npl_s_t s; | |
550 | +}; | |
551 | + | |
552 | +int npl_vs_init(npl_vs_t *vs); | |
553 | +npl_vs_t* npl_vs_new(void); | |
554 | +size_t npl_vs_count(npl_vs_t *vs); | |
555 | +size_t npl_vs_len(npl_vs_t *vs); | |
556 | +int npl_vs_enter(npl_vs_t *vs); | |
557 | +int npl_vs_leave(npl_vs_t *vs); | |
558 | +int npl_vs_is_empty(npl_vs_t *vs); | |
559 | +void npl_vs_empty(npl_vs_t *vs); | |
560 | +int npl_vs_push(npl_vs_t *vs, npl_val_t *val); | |
561 | +int npl_vs_pop(npl_vs_t *vs, npl_val_t *val_r); | |
562 | +int npl_vs_get(npl_vs_t *vs, size_t n, npl_val_t *val_r); | |
563 | +npl_val_t* npl_vs_ret(npl_vs_t *vs, size_t n); | |
564 | +void npl_vs_remove(npl_vs_t *vs, size_t n); | |
565 | + | |
566 | +// stack, objectのスタック | |
567 | +struct npl_stack_t { | |
568 | + npl_s_t s; | |
569 | +}; | |
570 | + | |
571 | +int npl_stack_init(npl_stack_t *stack); | |
503 | 572 | npl_stack_t* npl_stack_new(void); |
504 | -size_t npl_stack_count(npl_stack_t *s); | |
505 | -size_t npl_stack_pos(npl_stack_t *s); | |
506 | -int npl_stack_enter(npl_stack_t *s); | |
507 | -int npl_stack_leave(npl_stack_t *s); | |
508 | -int npl_stack_is_empty(npl_stack_t *s); | |
509 | -void npl_stack_empty(npl_stack_t *s); | |
510 | -int npl_stack_push(npl_stack_t *s, npl_val_t *val); | |
511 | -int npl_stack_pop(npl_stack_t *s, npl_val_t *val_r); | |
512 | -npl_val_t* npl_stack_ref(npl_stack_t *s, size_t pos); | |
573 | +size_t npl_stack_count(npl_stack_t *stack); | |
574 | +size_t npl_stack_len(npl_stack_t *stack); | |
575 | +int npl_stack_enter(npl_stack_t *stack); | |
576 | +int npl_stack_leave(npl_stack_t *stack); | |
577 | +int npl_stack_is_empty(npl_stack_t *stack); | |
578 | +void npl_stack_empty(npl_stack_t *stack); | |
579 | +int npl_stack_push(npl_stack_t *stack, npl_object_t *object); | |
580 | +npl_object_t* npl_stack_pop(npl_stack_t *stack); | |
581 | +npl_object_t* npl_stack_get(npl_stack_t *stack, size_t n); | |
582 | +void npl_stack_remove(npl_stack_t *stack, size_t n); | |
513 | 583 | |
514 | 584 | // q (Queue) |
515 | 585 | struct npl_q_t { |
@@ -523,14 +593,51 @@ | ||
523 | 593 | |
524 | 594 | npl_q_t* npl_q_alloc(npl_type_t *type, size_t el_size, size_t len); |
525 | 595 | npl_q_t* npl_q_new(size_t el_size, size_t len); |
526 | -size_t npl_q_el_size(npl_q_t *q); | |
596 | +size_t npl_q_size(npl_q_t *q); | |
527 | 597 | size_t npl_q_len(npl_q_t *q); |
598 | +int npl_q_is_full(npl_q_t *q); | |
599 | +int npl_q_is_empty(npl_q_t *q); | |
600 | +void npl_q_empty(npl_q_t *q); | |
528 | 601 | size_t npl_q_count(npl_q_t *q); |
529 | 602 | void* npl_q_push(npl_q_t *q); |
530 | -void* npl_q_pop(npl_q_t *q); | |
531 | -void npl_q_remove(npl_q_t *q); | |
532 | -void npl_q_clear(npl_q_t *q); | |
603 | +void* npl_q_ret(npl_q_t *q, size_t n); | |
604 | +void npl_q_remove(npl_q_t *q, size_t n); | |
533 | 605 | |
606 | +// vq | |
607 | +struct npl_vq_t { | |
608 | + npl_q_t q; | |
609 | +}; | |
610 | + | |
611 | +npl_vq_t* npl_vq_alloc(npl_type_t *type, size_t len); | |
612 | +npl_vq_t* npl_vq_new(size_t len); | |
613 | +size_t npl_vq_len(npl_vq_t *vq); | |
614 | +int npl_vq_is_full(npl_vq_t *vq); | |
615 | +int npl_vq_is_empty(npl_vq_t *vq); | |
616 | +void npl_vq_empty(npl_vq_t *vq); | |
617 | +size_t npl_vq_count(npl_vq_t *vq); | |
618 | +int npl_vq_push(npl_vq_t *vq, npl_val_t *val); | |
619 | +int npl_vq_pop(npl_vq_t *vq, npl_val_t *val_r); | |
620 | +int npl_vq_get(npl_vq_t *vq, size_t n, npl_val_t *val_r); | |
621 | +npl_val_t* npl_vq_ret(npl_vq_t *vq, size_t n); | |
622 | +void npl_vq_remove(npl_vq_t *vq, size_t n); | |
623 | + | |
624 | +// queue | |
625 | +struct npl_queue_t { | |
626 | + npl_q_t q; | |
627 | +}; | |
628 | + | |
629 | +npl_queue_t* npl_queue_alloc(npl_type_t *type, size_t len); | |
630 | +npl_queue_t* npl_queue_new(size_t len); | |
631 | +size_t npl_queue_len(npl_queue_t *queue); | |
632 | +int npl_queue_is_full(npl_queue_t *queue); | |
633 | +int npl_queue_is_empty(npl_queue_t *queue); | |
634 | +void npl_queue_empty(npl_queue_t *queue); | |
635 | +size_t npl_queue_count(npl_queue_t *queue); | |
636 | +int npl_queue_push(npl_queue_t *queue, npl_object_t *object); | |
637 | +npl_object_t* npl_queue_pop(npl_queue_t *queue); | |
638 | +npl_object_t* npl_queue_get(npl_queue_t *queue, size_t n); | |
639 | +void npl_queue_remove(npl_queue_t *queue, size_t n); | |
640 | + | |
534 | 641 | // tq (token q) |
535 | 642 | struct npl_tq_t { |
536 | 643 | npl_q_t q; |
@@ -538,9 +645,8 @@ | ||
538 | 645 | |
539 | 646 | npl_tq_t* npl_tq_new(size_t len); |
540 | 647 | npl_token_t* npl_tq_push(npl_tq_t *tq); |
541 | -npl_token_t* npl_tq_pop(npl_tq_t *tq); | |
542 | -void npl_tq_remove(npl_tq_t *tq); | |
543 | -void npl_tq_clear(npl_tq_t *tq); | |
648 | +npl_token_t* npl_tq_ret(npl_tq_t *tq, size_t n); | |
649 | +void npl_tq_remove(npl_tq_t *tq, size_t n); | |
544 | 650 | |
545 | 651 | // stream class |
546 | 652 | struct npl_stream_t { |
@@ -44,6 +44,11 @@ | ||
44 | 44 | return object; |
45 | 45 | } |
46 | 46 | |
47 | +npl_object_t* npl_object_new(void) | |
48 | +{ | |
49 | + return npl_object_alloc(npl_object_type); | |
50 | +} | |
51 | + | |
47 | 52 | // オブジェクトの参照カウントを増やす。 |
48 | 53 | void npl_object_ref(npl_object_t *object) |
49 | 54 | { |
@@ -7,10 +7,10 @@ | ||
7 | 7 | |
8 | 8 | assert(type); |
9 | 9 | assert(npl_type_check(npl_q_type, type) == 0); |
10 | + assert(el_size != 0); | |
11 | + assert(len != 0); | |
10 | 12 | |
11 | 13 | // キューのサイズを計算 |
12 | - if (el_size == 0 || len == 0) | |
13 | - return NULL; | |
14 | 14 | if (len >= (SIZE_MAX / el_size)) |
15 | 15 | return NULL; |
16 | 16 | if (npl_mul(el_size, len, &bytes)) |
@@ -35,7 +35,7 @@ | ||
35 | 35 | return npl_q_alloc(npl_q_type, el_size, len); |
36 | 36 | } |
37 | 37 | |
38 | -size_t npl_q_el_size(npl_q_t *q) | |
38 | +size_t npl_q_size(npl_q_t *q) | |
39 | 39 | { |
40 | 40 | assert(q); |
41 | 41 | return q->el_size; |
@@ -47,6 +47,32 @@ | ||
47 | 47 | return q->len; |
48 | 48 | } |
49 | 49 | |
50 | +int npl_q_is_full(npl_q_t *q) | |
51 | +{ | |
52 | + assert(q); | |
53 | + | |
54 | + if (q->count < q->len) | |
55 | + return 1; // no | |
56 | + return 0; | |
57 | +} | |
58 | + | |
59 | +int npl_q_is_empty(npl_q_t *q) | |
60 | +{ | |
61 | + assert(q); | |
62 | + | |
63 | + if (q->count != 0) | |
64 | + return 1; // no | |
65 | + return 0; | |
66 | +} | |
67 | + | |
68 | +void npl_q_empty(npl_q_t *q) | |
69 | +{ | |
70 | + assert(q); | |
71 | + | |
72 | + while (npl_q_is_empty(q)) | |
73 | + npl_q_remove(q, 1); | |
74 | +} | |
75 | + | |
50 | 76 | size_t npl_q_count(npl_q_t *q) |
51 | 77 | { |
52 | 78 | assert(q); |
@@ -70,7 +96,7 @@ | ||
70 | 96 | return (p + i); |
71 | 97 | } |
72 | 98 | |
73 | -void* npl_q_pop(npl_q_t *q) | |
99 | +void* npl_q_ret(npl_q_t *q, size_t n) | |
74 | 100 | { |
75 | 101 | unsigned char *p; |
76 | 102 | size_t i; |
@@ -79,35 +105,32 @@ | ||
79 | 105 | |
80 | 106 | if (q->count == 0) |
81 | 107 | return NULL; |
82 | - i = q->pos * q->el_size; | |
108 | + if (n >= q->count) | |
109 | + return NULL; | |
110 | + i = ((n + q->pos) % q->len) * q->el_size; | |
83 | 111 | p = q->chunk.chunk; |
84 | 112 | |
85 | 113 | return (p + i); |
86 | 114 | } |
87 | 115 | |
88 | -void npl_q_remove(npl_q_t *q) | |
116 | +void npl_q_remove(npl_q_t *q, size_t n) | |
89 | 117 | { |
90 | 118 | void *el; |
119 | + size_t i; | |
91 | 120 | |
92 | 121 | assert(q); |
93 | 122 | |
94 | - if (q->cleaner != NULL) { | |
95 | - el = npl_q_pop(q); | |
96 | - if (el != NULL) | |
97 | - q->cleaner(el); | |
123 | + for (i=0; i<n; i++) { | |
124 | + if (q->cleaner != NULL) { | |
125 | + el = npl_q_ret(q, 0); | |
126 | + if (el != NULL) | |
127 | + q->cleaner(el); | |
128 | + } | |
129 | + q->count -= 1; | |
130 | + q->pos = (q->pos + 1) % q->len; | |
98 | 131 | } |
99 | - q->count -= 1; | |
100 | - q->pos = (q->pos + 1) % q->len; | |
101 | 132 | } |
102 | 133 | |
103 | -void npl_q_clear(npl_q_t *q) | |
104 | -{ | |
105 | - assert(q); | |
106 | - | |
107 | - while (npl_q_pop(q)) | |
108 | - npl_q_remove(q); | |
109 | -} | |
110 | - | |
111 | 134 | // q クラスの型情報 |
112 | 135 | npl_type_t _npl_q_type = { |
113 | 136 | .object = { |
@@ -0,0 +1,120 @@ | ||
1 | +#include "global.h" | |
2 | + | |
3 | +static void _cleaner(void *data) | |
4 | +{ | |
5 | + npl_object_t **object = data; | |
6 | + | |
7 | + npl_object_unref(NPL_OBJECT(*object)); | |
8 | +} | |
9 | + | |
10 | +npl_queue_t* npl_queue_alloc(npl_type_t *type, size_t len) | |
11 | +{ | |
12 | + npl_queue_t *queue; | |
13 | + | |
14 | + assert(type); | |
15 | + assert(npl_type_check(npl_queue_type, type) == 0); | |
16 | + | |
17 | + queue = NPL_QUEUE(npl_q_alloc(type, sizeof(npl_object_t*), len)); | |
18 | + if (queue == NULL) | |
19 | + return NULL; | |
20 | + queue->q.cleaner = _cleaner; | |
21 | + | |
22 | + return queue; | |
23 | +} | |
24 | + | |
25 | +npl_queue_t* npl_queue_new(size_t len) | |
26 | +{ | |
27 | + return npl_queue_alloc(npl_queue_type, len); | |
28 | +} | |
29 | + | |
30 | +size_t npl_queue_len(npl_queue_t *queue) | |
31 | +{ | |
32 | + assert(queue); | |
33 | + return npl_q_len(&queue->q); | |
34 | +} | |
35 | + | |
36 | +int npl_queue_is_full(npl_queue_t *queue) | |
37 | +{ | |
38 | + assert(queue); | |
39 | + return npl_q_is_full(&queue->q); | |
40 | +} | |
41 | + | |
42 | +int npl_queue_is_empty(npl_queue_t *queue) | |
43 | +{ | |
44 | + assert(queue); | |
45 | + return npl_q_is_empty(&queue->q); | |
46 | +} | |
47 | + | |
48 | +void npl_queue_empty(npl_queue_t *queue) | |
49 | +{ | |
50 | + assert(queue); | |
51 | + npl_q_empty(&queue->q); | |
52 | +} | |
53 | + | |
54 | +size_t npl_queue_count(npl_queue_t *queue) | |
55 | +{ | |
56 | + assert(queue); | |
57 | + return npl_q_count(&queue->q); | |
58 | +} | |
59 | + | |
60 | +int npl_queue_push(npl_queue_t *queue, npl_object_t *object) | |
61 | +{ | |
62 | + npl_object_t **p; | |
63 | + | |
64 | + assert(queue); | |
65 | + assert(object); | |
66 | + | |
67 | + if ((p = npl_q_push(&queue->q)) == NULL) | |
68 | + return 1; // error | |
69 | + *p = object; | |
70 | + npl_object_ref(object); | |
71 | + return 0; | |
72 | +} | |
73 | + | |
74 | +npl_object_t* npl_queue_pop(npl_queue_t *queue) | |
75 | +{ | |
76 | + npl_object_t *object; | |
77 | + | |
78 | + object = npl_queue_get(queue, 0); | |
79 | + npl_queue_remove(queue, 1); | |
80 | + return object; | |
81 | +} | |
82 | + | |
83 | +npl_object_t* npl_queue_get(npl_queue_t *queue, size_t n) | |
84 | +{ | |
85 | + npl_object_t **p; | |
86 | + | |
87 | + assert(queue); | |
88 | + | |
89 | + if ((p = npl_q_ret(&queue->q, n)) == NULL) | |
90 | + return NULL; | |
91 | + npl_object_ref(*p); | |
92 | + return *p; | |
93 | +} | |
94 | + | |
95 | +void npl_queue_remove(npl_queue_t *queue, size_t n) | |
96 | +{ | |
97 | + assert(queue); | |
98 | + npl_q_remove(&queue->q, n); | |
99 | +} | |
100 | + | |
101 | +static void _destructor(npl_object_t *object) | |
102 | +{ | |
103 | + npl_queue_empty(NPL_QUEUE(object)); | |
104 | +} | |
105 | + | |
106 | +// queue クラスの型情報 | |
107 | +npl_type_t _npl_queue_type = { | |
108 | + .object = { | |
109 | + .type = &_npl_type_type, | |
110 | + .ref_count = 0, | |
111 | + .static_flag = 1, | |
112 | + }, | |
113 | + .name = L"queue", | |
114 | + .destructor = _destructor, | |
115 | + .parent = &_npl_q_type, | |
116 | + .size = sizeof(npl_queue_t), | |
117 | +}; | |
118 | + | |
119 | +npl_type_t *npl_queue_type = &_npl_queue_type; | |
120 | + |
@@ -0,0 +1,224 @@ | ||
1 | +#include "global.h" | |
2 | + | |
3 | +int npl_s_init(npl_s_t *s, size_t el_size) | |
4 | +{ | |
5 | + size_t def_bytes1; | |
6 | + size_t def_bytes2; | |
7 | + size_t expand_bytes; | |
8 | + | |
9 | + assert(s); | |
10 | + assert(el_size > 0); | |
11 | + | |
12 | + if (npl_mul(el_size, 64, &def_bytes1)) | |
13 | + return 1; // error | |
14 | + if (npl_mul(sizeof(size_t), 16, &def_bytes2)) | |
15 | + return 1; // error | |
16 | + if (npl_mul(el_size, 64, &expand_bytes)) | |
17 | + return 1; // error | |
18 | + | |
19 | + if (npl_buf_init(&s->buf, def_bytes1)) | |
20 | + return 1; // error | |
21 | + s->count_stack = npl_buf_new(def_bytes2); | |
22 | + if (s->count_stack == NULL) | |
23 | + return 1; // error | |
24 | + s->el_size = el_size; | |
25 | + s->count = 0; | |
26 | + s->count2 = 0; | |
27 | + s->expand_bytes; | |
28 | + s->count_stack_pos = 0; | |
29 | + s->cleaner = NULL; | |
30 | + | |
31 | + return 0; | |
32 | + | |
33 | +} | |
34 | + | |
35 | +npl_s_t* npl_s_new(size_t el_size) | |
36 | +{ | |
37 | + npl_s_t *s; | |
38 | + | |
39 | + s = NPL_S(npl_object_alloc(npl_s_type)); | |
40 | + if (s == NULL) | |
41 | + return NULL; | |
42 | + if (npl_s_init(s, el_size)) { | |
43 | + npl_object_unref(NPL_OBJECT(s)); | |
44 | + return NULL; | |
45 | + } | |
46 | + | |
47 | + return s; | |
48 | +} | |
49 | + | |
50 | +size_t npl_s_size(npl_s_t *s) | |
51 | +{ | |
52 | + assert(s); | |
53 | + return s->el_size; | |
54 | +} | |
55 | + | |
56 | +size_t npl_s_count(npl_s_t *s) | |
57 | +{ | |
58 | + assert(s); | |
59 | + return s->count; | |
60 | +} | |
61 | + | |
62 | +size_t npl_s_len(npl_s_t *s) | |
63 | +{ | |
64 | + assert(s); | |
65 | + return s->count + s->count2; | |
66 | +} | |
67 | + | |
68 | +int npl_s_enter(npl_s_t *s) | |
69 | +{ | |
70 | + size_t expand_bytes = sizeof(size_t) * 64; | |
71 | + size_t cs_size; | |
72 | + size_t *p; | |
73 | + size_t new_csp, new_count2; | |
74 | + | |
75 | + assert(s); | |
76 | + | |
77 | + if (npl_add(s->count_stack_pos, 1, &new_csp)) | |
78 | + return 2; // overflow | |
79 | + if (npl_add(s->count, s->count2, &new_count2)) | |
80 | + return 2; // overflow | |
81 | + | |
82 | + cs_size = s->count_stack->bytes / sizeof(size_t); | |
83 | + if (s->count_stack_pos < cs_size) | |
84 | + if (npl_buf_expand(s->count_stack, expand_bytes)) | |
85 | + return 1; // error | |
86 | + p = s->count_stack->buf; | |
87 | + p = p + s->count_stack_pos; | |
88 | + *p = s->count; | |
89 | + | |
90 | + s->count_stack_pos = new_csp; | |
91 | + s->count2 = new_count2; | |
92 | + s->count = 0; | |
93 | + return 0; | |
94 | +} | |
95 | + | |
96 | +int npl_s_leave(npl_s_t *s) | |
97 | +{ | |
98 | + size_t *p; | |
99 | + | |
100 | + assert(s); | |
101 | + | |
102 | + if (s->count_stack_pos == 0) | |
103 | + return 1; // 要素なし | |
104 | + npl_s_empty(s); | |
105 | + s->count_stack_pos -= 1; | |
106 | + p = s->count_stack->buf; | |
107 | + p = p + s->count_stack_pos; | |
108 | + s->count = *p; | |
109 | + s->count2 -= s->count; | |
110 | + return 0; | |
111 | +} | |
112 | + | |
113 | +int npl_s_is_empty(npl_s_t *s) | |
114 | +{ | |
115 | + assert(s); | |
116 | + if (s->count > 0) | |
117 | + return 1; // no | |
118 | + return 0; | |
119 | +} | |
120 | + | |
121 | +void npl_s_empty(npl_s_t *s) | |
122 | +{ | |
123 | + assert(s); | |
124 | + while (npl_s_is_empty(s)) | |
125 | + npl_s_remove(s, 1); | |
126 | +} | |
127 | + | |
128 | +void* npl_s_push(npl_s_t *s) | |
129 | +{ | |
130 | + unsigned char *p; | |
131 | + size_t pos, new_count; | |
132 | + | |
133 | + assert(s); | |
134 | + | |
135 | + if (npl_add(s->count, 1, &new_count)) | |
136 | + return NULL; | |
137 | + if ((s->buf.bytes / s->el_size) < new_count) | |
138 | + if (npl_buf_expand(&s->buf, s->expand_bytes)) | |
139 | + return NULL; | |
140 | + pos = npl_s_len(s); | |
141 | + if (npl_mul(pos, s->el_size, &pos)) | |
142 | + return NULL; | |
143 | + p = s->buf.buf; | |
144 | + if (p == NULL) | |
145 | + return NULL; | |
146 | + p = p + pos; | |
147 | + s->count = new_count; | |
148 | + | |
149 | + return p; | |
150 | +} | |
151 | + | |
152 | +void* npl_s_ret(npl_s_t *s, size_t n) | |
153 | +{ | |
154 | + unsigned char *p; | |
155 | + size_t pos; | |
156 | + | |
157 | + assert(s); | |
158 | + | |
159 | + pos = npl_s_len(s); | |
160 | + if (npl_sub(pos, 1, &pos)) | |
161 | + return NULL; | |
162 | + if (npl_sub(pos, n, &pos)) | |
163 | + return NULL; | |
164 | + if (npl_mul(pos, s->el_size, &pos)) | |
165 | + return NULL; | |
166 | + p = s->buf.buf; | |
167 | + if (p == NULL) | |
168 | + return NULL; | |
169 | + p = p + pos; | |
170 | + | |
171 | + return p; | |
172 | +} | |
173 | + | |
174 | +void npl_s_remove(npl_s_t *s, size_t n) | |
175 | +{ | |
176 | + unsigned char *p; | |
177 | + size_t pos; | |
178 | + size_t i; | |
179 | + | |
180 | + assert(s); | |
181 | + | |
182 | + for (i=0; i<n; i++) { | |
183 | + if (s->count == 0) | |
184 | + break; | |
185 | + pos = s->count2 + s->count - 1; | |
186 | + s->count -= 1; | |
187 | + if (s->cleaner != NULL) { | |
188 | + if (npl_mul(pos, s->el_size, &pos) == 0) { | |
189 | + if ((p = s->buf.buf) != NULL) { | |
190 | + p = p + pos; | |
191 | + s->cleaner(p); | |
192 | + } | |
193 | + } | |
194 | + } | |
195 | + } | |
196 | +} | |
197 | + | |
198 | +static void _destructor(npl_object_t *object) | |
199 | +{ | |
200 | + npl_s_t *s = NPL_S(object); | |
201 | + | |
202 | + while (npl_s_leave(s) == 0) | |
203 | + ; | |
204 | + if (s->count_stack != NULL) { | |
205 | + npl_object_unref(NPL_OBJECT(s->count_stack)); | |
206 | + s->count_stack = NULL; | |
207 | + } | |
208 | +} | |
209 | + | |
210 | +// s クラスの型情報 | |
211 | +npl_type_t _npl_s_type = { | |
212 | + .object = { | |
213 | + .type = &_npl_type_type, | |
214 | + .ref_count = 0, | |
215 | + .static_flag = 1, | |
216 | + }, | |
217 | + .name = L"s", | |
218 | + .destructor = _destructor, | |
219 | + .parent = &_npl_buf_type, | |
220 | + .size = sizeof(npl_s_t), | |
221 | +}; | |
222 | + | |
223 | +npl_type_t *npl_s_type = &_npl_s_type; | |
224 | + |
@@ -74,7 +74,7 @@ | ||
74 | 74 | return sb->buf.bytes / sizeof(wchar_t); |
75 | 75 | } |
76 | 76 | |
77 | -wchar_t* npl_sbuf_buf(npl_sbuf_t *sb) | |
77 | +wchar_t* npl_sbuf_ret(npl_sbuf_t *sb) | |
78 | 78 | { |
79 | 79 | assert(sb); |
80 | 80 | return sb->buf.buf; |
@@ -1,168 +1,115 @@ | ||
1 | 1 | #include "global.h" |
2 | 2 | |
3 | -int npl_stack_init(npl_stack_t *s) | |
3 | +static void _cleaner(void *data) | |
4 | 4 | { |
5 | - size_t default_bytes = sizeof(size_t) * 64; | |
5 | + npl_object_t *object = data; | |
6 | 6 | |
7 | - assert(s); | |
7 | + npl_object_unref(object); | |
8 | +} | |
8 | 9 | |
9 | - if (npl_array_init(&s->array, 256)) | |
10 | +int npl_stack_init(npl_stack_t *stack) | |
11 | +{ | |
12 | + assert(stack); | |
13 | + | |
14 | + if (npl_s_init(&stack->s, sizeof(npl_object_t*))) | |
10 | 15 | return 1; // error |
11 | - s->count_stack = npl_buf_new(default_bytes); | |
12 | - if (s->count_stack == NULL) | |
13 | - return 1; // error | |
14 | - s->count = 0; | |
15 | - s->count2 = 0; | |
16 | - s->count_stack_pos = 0; | |
17 | - | |
16 | + stack->s.cleaner = _cleaner; | |
18 | 17 | return 0; |
19 | 18 | } |
20 | 19 | |
21 | 20 | npl_stack_t* npl_stack_new(void) |
22 | 21 | { |
23 | - npl_stack_t *s; | |
22 | + npl_stack_t *stack; | |
24 | 23 | |
25 | - s = NPL_STACK(npl_object_alloc(npl_stack_type)); | |
26 | - if (s == NULL) | |
24 | + stack = NPL_STACK(npl_object_alloc(npl_stack_type)); | |
25 | + if (stack == NULL) | |
27 | 26 | return NULL; |
28 | - if (npl_stack_init(s)) { | |
29 | - npl_object_unref(NPL_OBJECT(s)); | |
27 | + if (npl_stack_init(stack)) { | |
28 | + npl_object_unref(NPL_OBJECT(stack)); | |
30 | 29 | return NULL; |
31 | 30 | } |
32 | 31 | |
33 | - return s; | |
32 | + return stack; | |
34 | 33 | } |
35 | 34 | |
36 | -size_t npl_stack_count(npl_stack_t *s) | |
35 | +size_t npl_stack_count(npl_stack_t *stack) | |
37 | 36 | { |
38 | - assert(s); | |
39 | - return s->count; | |
37 | + assert(stack); | |
38 | + return npl_s_count(&stack->s); | |
40 | 39 | } |
41 | 40 | |
42 | -size_t npl_stack_pos(npl_stack_t *s) | |
41 | +size_t npl_stack_len(npl_stack_t *stack) | |
43 | 42 | { |
44 | - assert(s); | |
45 | - return s->count + s->count2; | |
43 | + assert(stack); | |
44 | + return npl_s_len(&stack->s); | |
46 | 45 | } |
47 | 46 | |
48 | -int npl_stack_enter(npl_stack_t *s) | |
47 | +int npl_stack_enter(npl_stack_t *stack) | |
49 | 48 | { |
50 | - size_t expand_bytes = sizeof(size_t) * 64; | |
51 | - size_t cs_size; | |
52 | - size_t *p; | |
53 | - size_t new_csp, new_count2; | |
54 | - | |
55 | - assert(s); | |
56 | - | |
57 | - if (npl_add(s->count_stack_pos, 1, &new_csp)) | |
58 | - return 2; // overflow | |
59 | - if (npl_add(s->count, s->count2, &new_count2)) | |
60 | - return 2; // overflow | |
61 | - | |
62 | - cs_size = s->count_stack->bytes / sizeof(size_t); | |
63 | - if (s->count_stack_pos < cs_size) | |
64 | - if (npl_buf_expand(s->count_stack, expand_bytes)) | |
65 | - return 1; // error | |
66 | - p = s->count_stack->buf; | |
67 | - p = p + s->count_stack_pos; | |
68 | - *p = s->count; | |
69 | - | |
70 | - s->count_stack_pos = new_csp; | |
71 | - s->count2 = new_count2; | |
72 | - s->count = 0; | |
73 | - return 0; | |
49 | + assert(stack); | |
50 | + return npl_s_enter(&stack->s); | |
74 | 51 | } |
75 | 52 | |
76 | -int npl_stack_leave(npl_stack_t *s) | |
53 | +int npl_stack_leave(npl_stack_t *stack) | |
77 | 54 | { |
78 | - size_t *p; | |
79 | - | |
80 | - assert(s); | |
81 | - | |
82 | - if (s->count_stack_pos == 0) | |
83 | - return 1; // 要素なし | |
84 | - npl_stack_empty(s); | |
85 | - s->count_stack_pos -= 1; | |
86 | - p = s->count_stack->buf; | |
87 | - p = p + s->count_stack_pos; | |
88 | - s->count = *p; | |
89 | - s->count2 -= s->count; | |
90 | - return 0; | |
55 | + assert(stack); | |
56 | + return npl_s_leave(&stack->s); | |
91 | 57 | } |
92 | 58 | |
93 | -int npl_stack_is_empty(npl_stack_t *s) | |
59 | +int npl_stack_is_empty(npl_stack_t *stack) | |
94 | 60 | { |
95 | - assert(s); | |
96 | - if (s->count > 0) | |
97 | - return 1; // no | |
98 | - return 0; | |
61 | + assert(stack); | |
62 | + return npl_s_is_empty(&stack->s); | |
99 | 63 | } |
100 | 64 | |
101 | -void npl_stack_empty(npl_stack_t *s) | |
65 | +void npl_stack_empty(npl_stack_t *stack) | |
102 | 66 | { |
103 | - assert(s); | |
104 | - while (npl_stack_pop(s, NULL) == 0) | |
105 | - ; | |
67 | + assert(stack); | |
68 | + return npl_s_empty(&stack->s); | |
106 | 69 | } |
107 | 70 | |
108 | -int npl_stack_push(npl_stack_t *s, npl_val_t *val) | |
71 | +int npl_stack_push(npl_stack_t *stack, npl_object_t *object) | |
109 | 72 | { |
110 | - npl_val_t *v; | |
111 | - size_t pos, new_count; | |
73 | + npl_object_t **p; | |
112 | 74 | |
113 | - assert(s); | |
114 | - if (npl_add(s->count, 1, &new_count)) | |
75 | + assert(stack); | |
76 | + assert(object); | |
77 | + | |
78 | + if ((p = npl_s_push(&stack->s)) == NULL) | |
115 | 79 | return 1; // error |
116 | - pos = npl_stack_pos(s); | |
117 | - if (npl_array_set(&s->array, pos, val)) | |
118 | - return 1; // error | |
119 | - s->count = new_count; | |
80 | + *p = object; | |
81 | + npl_object_ref(*p); | |
120 | 82 | return 0; |
121 | 83 | } |
122 | 84 | |
123 | -int npl_stack_pop(npl_stack_t *s, npl_val_t *val_r) | |
85 | +npl_object_t* npl_stack_pop(npl_stack_t *stack) | |
124 | 86 | { |
125 | - npl_val_t *val; | |
87 | + npl_object_t *object; | |
126 | 88 | |
127 | - assert(s); | |
128 | - | |
129 | - if (s->count == 0) | |
130 | - return 1; // 要素なし | |
131 | - val = npl_stack_ref(s, 0); | |
132 | - if (val == NULL) | |
133 | - return 1; // 要素なし | |
134 | - if (val_r != NULL) | |
135 | - npl_val_copy(val_r, val); | |
136 | - npl_val_set_null(val); | |
137 | - s->count -= 1; | |
138 | - | |
139 | - return 0; | |
89 | + object = npl_stack_get(stack, 0); | |
90 | + npl_stack_remove(stack, 1); | |
91 | + return object; | |
140 | 92 | } |
141 | 93 | |
142 | -npl_val_t* npl_stack_ref(npl_stack_t *s, size_t pos) | |
94 | +npl_object_t* npl_stack_get(npl_stack_t *stack, size_t n) | |
143 | 95 | { |
144 | - size_t n, i; | |
96 | + npl_object_t **p; | |
145 | 97 | |
146 | - assert(s); | |
147 | - n = npl_stack_pos(s); | |
148 | - if (n < 1) | |
149 | - return NULL; // 要素なし | |
150 | - if (npl_sub(n-1, pos, &i)) | |
151 | - return NULL; // 要素なし | |
152 | - return npl_array_ref(&s->array, i); | |
98 | + assert(stack); | |
99 | + | |
100 | + if ((p = npl_s_ret(&stack->s, n)) == NULL) | |
101 | + return NULL; | |
102 | + npl_object_ref(*p); | |
103 | + return *p; | |
153 | 104 | } |
154 | 105 | |
155 | -static void _destructor(npl_object_t *object) | |
106 | +void npl_stack_remove(npl_stack_t *stack, size_t n) | |
156 | 107 | { |
157 | - npl_stack_t *s = NPL_STACK(object); | |
158 | - | |
159 | - if (s->count_stack != NULL) { | |
160 | - npl_object_unref(NPL_OBJECT(s->count_stack)); | |
161 | - s->count_stack = NULL; | |
162 | - } | |
108 | + assert(stack); | |
109 | + npl_s_remove(&stack->s, n); | |
163 | 110 | } |
164 | 111 | |
165 | -// スタッククラスの型情報 | |
112 | +// stack クラスの型情報 | |
166 | 113 | npl_type_t _npl_stack_type = { |
167 | 114 | .object = { |
168 | 115 | .type = &_npl_type_type, |
@@ -170,8 +117,8 @@ | ||
170 | 117 | .static_flag = 1, |
171 | 118 | }, |
172 | 119 | .name = L"stack", |
173 | - .destructor = _destructor, | |
174 | - .parent = &_npl_object_type, | |
120 | + .destructor = NULL, | |
121 | + .parent = &_npl_s_type, | |
175 | 122 | .size = sizeof(npl_stack_t), |
176 | 123 | }; |
177 | 124 |
@@ -49,7 +49,7 @@ | ||
49 | 49 | } |
50 | 50 | |
51 | 51 | // 文字列オブジェクトから文字列を返す |
52 | -wchar_t* npl_str_get(npl_str_t *str) | |
52 | +wchar_t* npl_str_ret(npl_str_t *str) | |
53 | 53 | { |
54 | 54 | assert(str); |
55 | 55 | return str->chunk.chunk; |
@@ -1,76 +0,0 @@ | ||
1 | -// スタックの基本的な操作 | |
2 | - | |
3 | -#include <stdio.h> | |
4 | -#include <stdlib.h> | |
5 | -#include <string.h> | |
6 | -#include "../../npl.h" | |
7 | - | |
8 | -void my_push(npl_stack_t *s, npl_val_t *val) | |
9 | -{ | |
10 | - if (npl_stack_push(s, val)) { | |
11 | - fprintf(stderr, "my_push() failed.\n"); | |
12 | - exit(1); | |
13 | - } | |
14 | -} | |
15 | - | |
16 | -int main(void) | |
17 | -{ | |
18 | - npl_stack_t *s; | |
19 | - npl_str_t *str; | |
20 | - npl_val_t v; | |
21 | - | |
22 | - if (npl_init()) { | |
23 | - fprintf(stderr, "npl_init() failed.\n"); | |
24 | - exit(1); | |
25 | - } | |
26 | - | |
27 | - // 新しいスタック・オブジェクトを作成する | |
28 | - if ((s = npl_stack_new()) == NULL) { | |
29 | - fprintf(stderr, "npl_stack_new() failed.\n"); | |
30 | - exit(1); | |
31 | - } | |
32 | - npl_val_begin(&v); | |
33 | - | |
34 | - // スタックに積む | |
35 | - npl_val_set_int(&v, 500); | |
36 | - my_push(s, &v); | |
37 | - | |
38 | - npl_val_set_float(&v, 56.789); | |
39 | - my_push(s, &v); | |
40 | - | |
41 | - str = npl_str_new(L"my message."); | |
42 | - if (str == NULL) { | |
43 | - fprintf(stderr, "npl_str_new() failed.\n"); | |
44 | - exit(1); | |
45 | - } | |
46 | - npl_val_set_str(&v, str); | |
47 | - my_push(s, &v); | |
48 | - npl_object_unref(NPL_OBJECT(str)); | |
49 | - | |
50 | - npl_val_set_str(&v, NULL); | |
51 | - my_push(s, &v); | |
52 | - | |
53 | - // スタックから取り出し、表示。 | |
54 | - while (npl_stack_pop(s, &v) == 0) { | |
55 | - if (npl_val_check(&v, NPL_VT_INT)) | |
56 | - printf("%d\n", v.i); | |
57 | - else if (npl_val_check(&v, NPL_VT_FLOAT)) | |
58 | - printf("%lf\n", v.f); | |
59 | - else if (npl_val_check(&v, NPL_VT_STR)) | |
60 | - printf("%S\n", npl_str_get(v.str)); | |
61 | - else if (npl_val_check(&v, NPL_VT_NULL)) | |
62 | - printf("(null)\n"); | |
63 | - } | |
64 | - | |
65 | - // 終了 | |
66 | - npl_val_end(&v); | |
67 | - npl_object_unref(NPL_OBJECT(s)); | |
68 | - | |
69 | - if (npl_final()) { | |
70 | - fprintf(stderr, "npl_final() failed.\n"); | |
71 | - exit(1); | |
72 | - } | |
73 | - | |
74 | - return 0; | |
75 | -} | |
76 | - |
@@ -1,99 +0,0 @@ | ||
1 | -// enter と leave。 | |
2 | -// | |
3 | -// npl_stack_enter() は現在のスタックに、 | |
4 | -// 新しいローカルなスタックを作る。 | |
5 | -// (以前に積まれた内容を保存した上で、 | |
6 | -// 新しい空のスタックにする。) | |
7 | -// | |
8 | -// npl_stack_leave() はローカルなスタック | |
9 | -// を抜け、以前の内容に戻す。 | |
10 | -// | |
11 | -// これらは何重にもネスト可能。 | |
12 | - | |
13 | -#include <stdio.h> | |
14 | -#include <stdlib.h> | |
15 | -#include <string.h> | |
16 | -#include "../../npl.h" | |
17 | - | |
18 | -void my_push(npl_stack_t *s, npl_val_t *val) | |
19 | -{ | |
20 | - if (npl_stack_push(s, val)) { | |
21 | - fprintf(stderr, "my_push() failed.\n"); | |
22 | - exit(1); | |
23 | - } | |
24 | -} | |
25 | - | |
26 | -void push_int(npl_stack_t *s, int i) | |
27 | -{ | |
28 | - npl_val_t val; | |
29 | - | |
30 | - npl_val_begin(&val); | |
31 | - npl_val_set_int(&val, i); | |
32 | - my_push(s, &val); | |
33 | - npl_val_end(&val); | |
34 | -} | |
35 | - | |
36 | -// スタックから int 型のデータを取り出し、表示。 | |
37 | -void show_stack(npl_stack_t *s) | |
38 | -{ | |
39 | - npl_val_t val; | |
40 | - | |
41 | - npl_val_begin(&val); | |
42 | - while (npl_stack_pop(s, &val) == 0) { | |
43 | - if (npl_val_check(&val, NPL_VT_INT)) { | |
44 | - printf("%d\n", val.i); | |
45 | - } else { | |
46 | - printf("(unknown value.)\n"); | |
47 | - } | |
48 | - } | |
49 | - npl_val_end(&val); | |
50 | -} | |
51 | - | |
52 | -int main(void) | |
53 | -{ | |
54 | - npl_stack_t *s; | |
55 | - | |
56 | - if (npl_init()) { | |
57 | - fprintf(stderr, "npl_init() failed.\n"); | |
58 | - exit(1); | |
59 | - } | |
60 | - | |
61 | - // 新しいスタック・オブジェクトを作成する | |
62 | - if ((s = npl_stack_new()) == NULL) { | |
63 | - fprintf(stderr, "npl_stack_new() failed.\n"); | |
64 | - exit(1); | |
65 | - } | |
66 | - | |
67 | - // スタック操作 | |
68 | - push_int(s, 1); | |
69 | - push_int(s, 2); | |
70 | - push_int(s, 3); | |
71 | - | |
72 | - npl_stack_enter(s); | |
73 | - push_int(s, 10); | |
74 | - push_int(s, 20); | |
75 | - push_int(s, 30); | |
76 | - | |
77 | - npl_stack_enter(s); | |
78 | - push_int(s, 100); | |
79 | - | |
80 | - npl_stack_enter(s); | |
81 | - push_int(s, 2000); | |
82 | - | |
83 | - npl_stack_leave(s); | |
84 | - npl_stack_leave(s); | |
85 | - | |
86 | - // 現在の(ローカルの)スタックの中を表示。 | |
87 | - show_stack(s); | |
88 | - | |
89 | - // オブジェクトは、もう参照しない | |
90 | - npl_object_unref(NPL_OBJECT(s)); | |
91 | - | |
92 | - if (npl_final()) { | |
93 | - fprintf(stderr, "npl_final() failed.\n"); | |
94 | - exit(1); | |
95 | - } | |
96 | - | |
97 | - return 0; | |
98 | -} | |
99 | - |
@@ -1,173 +0,0 @@ | ||
1 | -// test3.c | |
2 | -// | |
3 | -// 簡易なスタック式電卓。 | |
4 | -// | |
5 | -// スタックを使って、 | |
6 | -// 簡単な四則演算を行う。 | |
7 | -// (後置記法で計算する) | |
8 | - | |
9 | -#include <stdio.h> | |
10 | -#include <stdlib.h> | |
11 | -#include <string.h> | |
12 | -#include "../../npl.h" | |
13 | - | |
14 | -int pop_int(npl_stack_t *s) | |
15 | -{ | |
16 | - int i; | |
17 | - npl_val_t val; | |
18 | - | |
19 | - npl_val_begin(&val); | |
20 | - if (npl_stack_pop(s, &val)) { | |
21 | - fprintf(stderr, "pop_int() failed.\n"); | |
22 | - exit(1); | |
23 | - } | |
24 | - if (!npl_val_check(&val, NPL_VT_INT)) { | |
25 | - fprintf(stderr, "pop_int() failed.\n"); | |
26 | - exit(1); | |
27 | - } | |
28 | - i = val.i; | |
29 | - npl_val_end(&val); | |
30 | - | |
31 | - return i; | |
32 | -} | |
33 | - | |
34 | -void my_push(npl_stack_t *s, npl_val_t *val) | |
35 | -{ | |
36 | - if (npl_stack_push(s, val)) { | |
37 | - fprintf(stderr, "my_push() failed.\n"); | |
38 | - exit(1); | |
39 | - } | |
40 | -} | |
41 | - | |
42 | -void push_int(npl_stack_t *s, int i) | |
43 | -{ | |
44 | - npl_val_t val; | |
45 | - | |
46 | - npl_val_begin(&val); | |
47 | - npl_val_set_int(&val, i); | |
48 | - my_push(s, &val); | |
49 | - npl_val_end(&val); | |
50 | -} | |
51 | - | |
52 | -void push_op(npl_stack_t *s, npl_operator_t op) | |
53 | -{ | |
54 | - npl_val_t val; | |
55 | - | |
56 | - npl_val_begin(&val); | |
57 | - npl_val_set_op(&val, op); | |
58 | - my_push(s, &val); | |
59 | - npl_val_end(&val); | |
60 | -} | |
61 | - | |
62 | -int op_add(npl_stack_t *s) | |
63 | -{ | |
64 | - int a, b; | |
65 | - | |
66 | - b = pop_int(s); | |
67 | - a = pop_int(s); | |
68 | - push_int(s, a + b); | |
69 | - | |
70 | - return 0; | |
71 | -} | |
72 | - | |
73 | -int op_sub(npl_stack_t *s) | |
74 | -{ | |
75 | - int a, b; | |
76 | - | |
77 | - b = pop_int(s); | |
78 | - a = pop_int(s); | |
79 | - push_int(s, a - b); | |
80 | - | |
81 | - return 0; | |
82 | -} | |
83 | - | |
84 | -int op_mul(npl_stack_t *s) | |
85 | -{ | |
86 | - int a, b; | |
87 | - | |
88 | - b = pop_int(s); | |
89 | - a = pop_int(s); | |
90 | - push_int(s, a * b); | |
91 | - | |
92 | - return 0; | |
93 | -} | |
94 | - | |
95 | -int op_div(npl_stack_t *s) | |
96 | -{ | |
97 | - int a, b; | |
98 | - | |
99 | - b = pop_int(s); | |
100 | - a = pop_int(s); | |
101 | - push_int(s, a / b); | |
102 | - | |
103 | - return 0; | |
104 | -} | |
105 | - | |
106 | -int calc(npl_stack_t *s, npl_stack_t *t) | |
107 | -{ | |
108 | - int result = 0; | |
109 | - npl_val_t val; | |
110 | - | |
111 | - npl_stack_empty(t); | |
112 | - | |
113 | - npl_val_begin(&val); | |
114 | - while (npl_stack_pop(s, &val) == 0) { | |
115 | - if (npl_val_check(&val, NPL_VT_INT)) { | |
116 | - push_int(t, val.i); | |
117 | - } else if (npl_val_check(&val, NPL_VT_OPERATOR)) { | |
118 | - if (val.op != NULL) { | |
119 | - if (val.op(t)) { | |
120 | - result = 1; | |
121 | - break; | |
122 | - } | |
123 | - } | |
124 | - } | |
125 | - } | |
126 | - npl_val_end(&val); | |
127 | - | |
128 | - return result; | |
129 | -} | |
130 | - | |
131 | -int main(void) | |
132 | -{ | |
133 | - npl_stack_t *s, *t; | |
134 | - | |
135 | - if (npl_init()) { | |
136 | - fprintf(stderr, "npl_init() failed.\n"); | |
137 | - exit(1); | |
138 | - } | |
139 | - | |
140 | - // 新しいスタック・オブジェクトを作成する | |
141 | - if ((s = npl_stack_new()) == NULL) { | |
142 | - fprintf(stderr, "npl_stack_new() failed.\n"); | |
143 | - exit(1); | |
144 | - } | |
145 | - if ((t = npl_stack_new()) == NULL) { | |
146 | - fprintf(stderr, "npl_stack_new() failed.\n"); | |
147 | - exit(1); | |
148 | - } | |
149 | - | |
150 | - // (100 - 28) / 12 --> <100><28><-><12</> | |
151 | - push_op(s, op_div); | |
152 | - push_int(s, 12); | |
153 | - push_op(s, op_sub); | |
154 | - push_int(s, 28); | |
155 | - push_int(s, 100); | |
156 | - | |
157 | - if (calc(s, t) == 0) | |
158 | - printf("%d\n", pop_int(t)); | |
159 | - else | |
160 | - fprintf(stderr, "calc() failed.\n"); | |
161 | - | |
162 | - // オブジェクトは、もう参照しない | |
163 | - npl_object_unref(NPL_OBJECT(t)); | |
164 | - npl_object_unref(NPL_OBJECT(s)); | |
165 | - | |
166 | - if (npl_final()) { | |
167 | - fprintf(stderr, "npl_final() failed.\n"); | |
168 | - exit(1); | |
169 | - } | |
170 | - | |
171 | - return 0; | |
172 | -} | |
173 | - |
@@ -1,16 +0,0 @@ | ||
1 | -all: test1 test2 test3 | |
2 | - | |
3 | -test1: test1.c | |
4 | - gcc -otest1 test1.c ../../libnpl.a | |
5 | - | |
6 | -test2: test2.c | |
7 | - gcc -otest2 test2.c ../../libnpl.a | |
8 | - | |
9 | -test3: test3.c | |
10 | - gcc -otest3 test3.c ../../libnpl.a | |
11 | - | |
12 | -clean: | |
13 | - rm -f test1 | |
14 | - rm -f test2 | |
15 | - rm -f test3 | |
16 | - |
@@ -47,7 +47,7 @@ | ||
47 | 47 | } |
48 | 48 | |
49 | 49 | // 文字列の内容を表示する |
50 | - printf("\"%S\"\n", npl_str_get(str)); | |
50 | + printf("\"%S\"\n", npl_str_ret(str)); | |
51 | 51 | |
52 | 52 | // sbuf, str の使用を終える |
53 | 53 | npl_object_unref(NPL_OBJECT(str)); |
@@ -42,7 +42,7 @@ | ||
42 | 42 | |
43 | 43 | // sbuf の各要素を表示する |
44 | 44 | for (i=0; i < npl_sbuf_size(sbuf); i++) { |
45 | - w = npl_sbuf_buf(sbuf); | |
45 | + w = npl_sbuf_ret(sbuf); | |
46 | 46 | if (w[i] == L'\0') { |
47 | 47 | printf("[%u] (NUL)\n", i); |
48 | 48 | break; |
@@ -0,0 +1,20 @@ | ||
1 | +all: ss qs ss2 qs2 | |
2 | + | |
3 | +ss: ss.c | |
4 | + gcc -oss ss.c ../../libnpl.a | |
5 | + | |
6 | +qs: qs.c | |
7 | + gcc -oqs qs.c ../../libnpl.a | |
8 | + | |
9 | +ss2: ss2.c | |
10 | + gcc -oss2 ss2.c ../../libnpl.a | |
11 | + | |
12 | +qs2: qs2.c | |
13 | + gcc -oqs2 qs2.c ../../libnpl.a | |
14 | + | |
15 | +clean: | |
16 | + rm -f ss | |
17 | + rm -f qs | |
18 | + rm -f ss2 | |
19 | + rm -f qs2 | |
20 | + |
@@ -0,0 +1,79 @@ | ||
1 | +// queue string | |
2 | +// | |
3 | +// キューにストリングでも詰め込んでみるテスト、 | |
4 | +// の意味。 | |
5 | +// | |
6 | +// 内容: | |
7 | +// コマンドライン引数の文字列を | |
8 | +// 1文字づつすべてスタックへプッシュする。 | |
9 | +// その後、積んだ内容を順にポップし | |
10 | +// 出力する。 内容はそのまま表示されるが、 | |
11 | +// (スタックと異なりキューは自動的に | |
12 | +// バッファを増やさないので、)格納できる | |
13 | +// 量を超えるとエラーになる。 | |
14 | +// 格納できる文字数は、あえて小さめの | |
15 | +// 4文字まで。 | |
16 | +// | |
17 | +// 実行: ./qs ab cd 12 34 | |
18 | +// 結果: abcd1234 | |
19 | +// | |
20 | +// ※ q クラス (npl_q_t型)のテストです。 | |
21 | + | |
22 | +#include <stdio.h> | |
23 | +#include <stdlib.h> | |
24 | +#include <string.h> | |
25 | +#include "../../npl.h" | |
26 | + | |
27 | +int main(int argc, char *argv[]) | |
28 | +{ | |
29 | + npl_q_t *q; | |
30 | + char *p, *str; | |
31 | + int i; | |
32 | + size_t j; | |
33 | + | |
34 | + if (npl_init()) { | |
35 | + fprintf(stderr, "npl_init() failed.\n"); | |
36 | + exit(1); | |
37 | + } | |
38 | + | |
39 | + // charサイズを4つまで格納できるキューを生成 | |
40 | + q = npl_q_new(sizeof(char), 4); | |
41 | + if (q == NULL) { | |
42 | + fprintf(stderr, "npl_q_new() failed.\n"); | |
43 | + exit(1); | |
44 | + } | |
45 | + | |
46 | + // 各々のコマンドライン引数に対して処理を行う | |
47 | + for (i=1; i<argc; i++) { | |
48 | + str = argv[i]; | |
49 | + | |
50 | + // キューに1文字づつ積む。 | |
51 | + // ただし、キューの容量を超えると | |
52 | + // buffer overflow. と表示して終了。 | |
53 | + for (j=0; str[j] != '\0'; j++) { | |
54 | + p = npl_q_push(q); | |
55 | + if (p == NULL) { | |
56 | + fprintf(stderr, "buffer overflow.\n"); | |
57 | + exit(1); | |
58 | + } | |
59 | + *p = str[j]; | |
60 | + } | |
61 | + | |
62 | + // キューから1文字づつ取り出し、表示 | |
63 | + while ((p = npl_q_ret(q, 0)) != NULL) { | |
64 | + printf("%c", *p); | |
65 | + npl_q_remove(q, 1); | |
66 | + } | |
67 | + } | |
68 | + printf("\n"); | |
69 | + | |
70 | + // 終了 | |
71 | + npl_object_unref(NPL_OBJECT(q)); | |
72 | + | |
73 | + if (npl_final()) { | |
74 | + fprintf(stderr, "npl_final() failed.\n"); | |
75 | + exit(1); | |
76 | + } | |
77 | + | |
78 | + return 0; | |
79 | +} |
@@ -0,0 +1,84 @@ | ||
1 | +// queue string 2 | |
2 | +// | |
3 | +// キューにストリングでも詰め込んでみるテスト | |
4 | +// その2、の意味。 | |
5 | +// | |
6 | +// ※ queue クラス (npl_queue_t型)のテストです。 | |
7 | + | |
8 | +#include <stdio.h> | |
9 | +#include <stdlib.h> | |
10 | +#include <string.h> | |
11 | +#include "../../npl.h" | |
12 | + | |
13 | +int main(int argc, char *argv[]) | |
14 | +{ | |
15 | + npl_queue_t *queue; | |
16 | + npl_mbstr_t *mbstr; | |
17 | + npl_object_t *done; | |
18 | + int i; | |
19 | + int running; | |
20 | + | |
21 | + if (npl_init()) { | |
22 | + fprintf(stderr, "npl_init() failed.\n"); | |
23 | + exit(1); | |
24 | + } | |
25 | + | |
26 | + // あえて、小さめのキューを生成。 | |
27 | + queue = npl_queue_new(2); | |
28 | + if (queue == NULL) { | |
29 | + fprintf(stderr, "npl_queue_new() failed.\n"); | |
30 | + exit(1); | |
31 | + } | |
32 | + | |
33 | + done = npl_object_new(); | |
34 | + if (done == NULL) { | |
35 | + fprintf(stderr, "npl_object_new() failed.\n"); | |
36 | + exit(1); | |
37 | + } | |
38 | + | |
39 | + i = 1; | |
40 | + running = 1; | |
41 | + while (running) { | |
42 | + | |
43 | + // 文字列を可能な限り詰め込む。 | |
44 | + while (npl_queue_is_full(queue)) { | |
45 | + if (i == argc) { | |
46 | + npl_queue_push(queue, done); | |
47 | + break; | |
48 | + } | |
49 | + | |
50 | + mbstr = npl_mbstr_new(argv[i]); | |
51 | + if (mbstr == NULL) { | |
52 | + fprintf(stderr, "npl_mbstr_new() failed.\n"); | |
53 | + exit(1); | |
54 | + } | |
55 | + i += 1; | |
56 | + npl_queue_push(queue, NPL_OBJECT(mbstr)); | |
57 | + npl_object_unref(NPL_OBJECT(mbstr)); | |
58 | + } | |
59 | + | |
60 | + // オブジェクトを取り出して表示 | |
61 | + while (npl_queue_is_empty(queue)) { | |
62 | + npl_object_t *obj = npl_queue_pop(queue); | |
63 | + | |
64 | + if (obj == done) { | |
65 | + running = 0; | |
66 | + } else { | |
67 | + mbstr = NPL_MBSTR(obj); | |
68 | + printf("%s\n", npl_mbstr_ret(mbstr)); | |
69 | + } | |
70 | + npl_object_unref(obj); | |
71 | + } | |
72 | + } | |
73 | + | |
74 | + // 終了 | |
75 | + npl_object_unref(done); | |
76 | + npl_object_unref(NPL_OBJECT(queue)); | |
77 | + | |
78 | + if (npl_final()) { | |
79 | + fprintf(stderr, "npl_final() failed.\n"); | |
80 | + exit(1); | |
81 | + } | |
82 | + | |
83 | + return 0; | |
84 | +} |
@@ -0,0 +1,71 @@ | ||
1 | +// stack string | |
2 | +// | |
3 | +// スタックにストリングでも詰め込んでみるテスト、 | |
4 | +// の意味。 | |
5 | +// | |
6 | +// 内容: | |
7 | +// コマンドライン引数の文字列を | |
8 | +// 1文字づつすべてスタックへプッシュする。 | |
9 | +// その後、積んだ内容を順にポップし | |
10 | +// 出力する。 結果的に逆の文字列が | |
11 | +// 表示される。 | |
12 | +// | |
13 | +// 実行: ./ss a b c def 123 | |
14 | +// 結果: 321fedcba | |
15 | +// | |
16 | +// ※ s クラス(npl_s_t型)のテストです。 | |
17 | + | |
18 | +#include <stdio.h> | |
19 | +#include <stdlib.h> | |
20 | +#include <string.h> | |
21 | +#include "../../npl.h" | |
22 | + | |
23 | +int main(int argc, char *argv[]) | |
24 | +{ | |
25 | + npl_s_t *s; | |
26 | + char *p, *str; | |
27 | + int i; | |
28 | + size_t j; | |
29 | + | |
30 | + if (npl_init()) { | |
31 | + fprintf(stderr, "npl_init() failed.\n"); | |
32 | + exit(1); | |
33 | + } | |
34 | + | |
35 | + // charサイズのスタックを生成 | |
36 | + s = npl_s_new(sizeof(char)); | |
37 | + if (s == NULL) { | |
38 | + fprintf(stderr, "npl_s_new() failed.\n"); | |
39 | + exit(1); | |
40 | + } | |
41 | + | |
42 | + // コマンドライン文字列を1文字づつスタックに積む | |
43 | + for (i=1; i<argc; i++) { | |
44 | + str = argv[i]; | |
45 | + for (j=0; str[j] != '\0'; j++) { | |
46 | + p = npl_s_push(s); | |
47 | + if (p == NULL) { | |
48 | + fprintf(stderr, "npl_s_push() failed.\n"); | |
49 | + exit(1); | |
50 | + } | |
51 | + *p = str[j]; | |
52 | + } | |
53 | + } | |
54 | + | |
55 | + // スタックから1文字づつ取り出し、表示 | |
56 | + while ((p = npl_s_ret(s, 0)) != NULL) { | |
57 | + printf("%c", *p); | |
58 | + npl_s_remove(s, 1); | |
59 | + } | |
60 | + printf("\n"); | |
61 | + | |
62 | + // 終了 | |
63 | + npl_object_unref(NPL_OBJECT(s)); | |
64 | + | |
65 | + if (npl_final()) { | |
66 | + fprintf(stderr, "npl_final() failed.\n"); | |
67 | + exit(1); | |
68 | + } | |
69 | + | |
70 | + return 0; | |
71 | +} |
@@ -0,0 +1,81 @@ | ||
1 | +// stack string 2 | |
2 | +// | |
3 | +// スタックにストリングでも詰め込んでみるテスト | |
4 | +// その2、の意味。 | |
5 | +// | |
6 | +// 内容: | |
7 | +// スタックにコマンドライン引数の | |
8 | +// C文字列を積む。 | |
9 | +// (C文字列に対応した mbstr オブジェクト | |
10 | +// を積む。) | |
11 | +// その後、スタックから積まれた文字列を | |
12 | +// ポップして表示する。 したがって、 | |
13 | +// 逆の順序で文字列が表示される。 | |
14 | +// | |
15 | +// 実行: ./ss2 abc 123 XYZ | |
16 | +// 結果: | |
17 | +// XYZ | |
18 | +// 123 | |
19 | +// abc | |
20 | +// | |
21 | +// ※ stack クラス(npl_stack_t型)のテストです。 | |
22 | + | |
23 | +#include <stdio.h> | |
24 | +#include <stdlib.h> | |
25 | +#include <string.h> | |
26 | +#include "../../npl.h" | |
27 | + | |
28 | +int main(int argc, char *argv[]) | |
29 | +{ | |
30 | + npl_stack_t *stack; | |
31 | + npl_mbstr_t *mbstr; | |
32 | + int i; | |
33 | + | |
34 | + if (npl_init()) { | |
35 | + fprintf(stderr, "npl_init() failed.\n"); | |
36 | + exit(1); | |
37 | + } | |
38 | + | |
39 | + // スタックを生成する。 | |
40 | + // npl_stack_t型は、オブジェクト専用のスタック型。 | |
41 | + stack = npl_stack_new(); | |
42 | + if (stack == NULL) { | |
43 | + fprintf(stderr, "npl_stack_new() failed.\n"); | |
44 | + exit(1); | |
45 | + } | |
46 | + | |
47 | + // 各々のコマンドライン引数文字列から | |
48 | + // mbstr オブジェクトを生成し、 | |
49 | + // スタックにプッシュする。 | |
50 | + for (i=1; i<argc; i++) { | |
51 | + mbstr = npl_mbstr_new(argv[i]); | |
52 | + if (mbstr == NULL) { | |
53 | + fprintf(stderr, "npl_mbstr_new() failed.\n"); | |
54 | + exit(1); | |
55 | + } | |
56 | + if (npl_stack_push(stack, NPL_OBJECT(mbstr))) { | |
57 | + fprintf(stderr, "npl_stack_push() failed.\n"); | |
58 | + exit(1); | |
59 | + } | |
60 | + npl_object_unref(NPL_OBJECT(mbstr)); | |
61 | + } | |
62 | + | |
63 | + // スタックからオブジェクトを取り出して、出力する。 | |
64 | + while (npl_stack_is_empty(stack)) { | |
65 | + npl_object_t *obj = npl_stack_pop(stack); | |
66 | + | |
67 | + mbstr = NPL_MBSTR(obj); | |
68 | + printf("%s\n", npl_mbstr_ret(mbstr)); | |
69 | + npl_object_unref(NPL_OBJECT(mbstr)); | |
70 | + } | |
71 | + | |
72 | + // 終了 | |
73 | + npl_object_unref(NPL_OBJECT(stack)); | |
74 | + | |
75 | + if (npl_final()) { | |
76 | + fprintf(stderr, "npl_final() failed.\n"); | |
77 | + exit(1); | |
78 | + } | |
79 | + | |
80 | + return 0; | |
81 | +} |
@@ -19,10 +19,10 @@ | ||
19 | 19 | m2 = npl_mbstr_new_from_wcs(L"たちつてと"); |
20 | 20 | |
21 | 21 | if (s1 && s2 && m1 && m2) { |
22 | - printf("%S\n", npl_str_get(s1)); | |
23 | - printf("%S\n", npl_str_get(s2)); | |
24 | - printf("%s\n", npl_mbstr_get(m1)); | |
25 | - printf("%s\n", npl_mbstr_get(m2)); | |
22 | + printf("%S\n", npl_str_ret(s1)); | |
23 | + printf("%S\n", npl_str_ret(s2)); | |
24 | + printf("%s\n", npl_mbstr_ret(m1)); | |
25 | + printf("%s\n", npl_mbstr_ret(m2)); | |
26 | 26 | } else { |
27 | 27 | fprintf(stderr, "error!\n"); |
28 | 28 | exit(1); |
@@ -58,7 +58,7 @@ | ||
58 | 58 | if (v.object->type == npl_str_type) { |
59 | 59 | printf("[%d]: %S\n", |
60 | 60 | i, |
61 | - npl_str_get(NPL_STR(v.object))); | |
61 | + npl_str_ret(NPL_STR(v.object))); | |
62 | 62 | } else { |
63 | 63 | printf("[%d]: ?\n", i); |
64 | 64 | } |
@@ -43,24 +43,18 @@ | ||
43 | 43 | return npl_q_push(&tq->q); |
44 | 44 | } |
45 | 45 | |
46 | -npl_token_t* npl_tq_pop(npl_tq_t *tq) | |
46 | +npl_token_t* npl_tq_ret(npl_tq_t *tq, size_t n) | |
47 | 47 | { |
48 | 48 | assert(tq); |
49 | - return npl_q_pop(&tq->q); | |
49 | + return npl_q_ret(&tq->q, n); | |
50 | 50 | } |
51 | 51 | |
52 | -void npl_tq_remove(npl_tq_t *tq) | |
52 | +void npl_tq_remove(npl_tq_t *tq, size_t n) | |
53 | 53 | { |
54 | 54 | assert(tq); |
55 | - npl_q_remove(&tq->q); | |
55 | + npl_q_remove(&tq->q, n); | |
56 | 56 | } |
57 | 57 | |
58 | -void npl_tq_clear(npl_tq_t *tq) | |
59 | -{ | |
60 | - assert(tq); | |
61 | - npl_q_clear(&tq->q); | |
62 | -} | |
63 | - | |
64 | 58 | static void _destructor(npl_object_t *object) |
65 | 59 | { |
66 | 60 | _final(NPL_TQ(object)); |
@@ -65,7 +65,7 @@ | ||
65 | 65 | |
66 | 66 | // tuple 内部の val への参照を返す。 |
67 | 67 | // (勝手に npl_val_end() で終了してはいけない) |
68 | -npl_val_t* npl_tuple_ref(npl_tuple_t *tuple, size_t i) | |
68 | +npl_val_t* npl_tuple_ret(npl_tuple_t *tuple, size_t i) | |
69 | 69 | { |
70 | 70 | npl_val_t *p; |
71 | 71 |
@@ -18,8 +18,12 @@ | ||
18 | 18 | case NPL_VT_FUNC: |
19 | 19 | case NPL_VT_MEMBER: |
20 | 20 | case NPL_VT_STATE: |
21 | + case NPL_VT_S: | |
22 | + case NPL_VT_VS: | |
21 | 23 | case NPL_VT_STACK: |
22 | 24 | case NPL_VT_Q: |
25 | + case NPL_VT_VQ: | |
26 | + case NPL_VT_QUEUE: | |
23 | 27 | case NPL_VT_TQ: |
24 | 28 | case NPL_VT_STREAM: |
25 | 29 | if (val->object != NULL) |
@@ -46,8 +50,12 @@ | ||
46 | 50 | case NPL_VT_FUNC: |
47 | 51 | case NPL_VT_MEMBER: |
48 | 52 | case NPL_VT_STATE: |
53 | + case NPL_VT_S: | |
54 | + case NPL_VT_VS: | |
49 | 55 | case NPL_VT_STACK: |
50 | 56 | case NPL_VT_Q: |
57 | + case NPL_VT_VQ: | |
58 | + case NPL_VT_QUEUE: | |
51 | 59 | case NPL_VT_TQ: |
52 | 60 | case NPL_VT_STREAM: |
53 | 61 | if (val->object != NULL) |
@@ -105,10 +113,18 @@ | ||
105 | 113 | return npl_member_type; |
106 | 114 | case NPL_VT_STATE: |
107 | 115 | return npl_state_type; |
116 | + case NPL_VT_S: | |
117 | + return npl_s_type; | |
118 | + case NPL_VT_VS: | |
119 | + return npl_vs_type; | |
108 | 120 | case NPL_VT_STACK: |
109 | 121 | return npl_stack_type; |
110 | 122 | case NPL_VT_Q: |
111 | 123 | return npl_q_type; |
124 | + case NPL_VT_VQ: | |
125 | + return npl_vq_type; | |
126 | + case NPL_VT_QUEUE: | |
127 | + return npl_queue_type; | |
112 | 128 | case NPL_VT_TQ: |
113 | 129 | return npl_tq_type; |
114 | 130 | case NPL_VT_STREAM: |
@@ -181,8 +197,12 @@ | ||
181 | 197 | case NPL_VT_FUNC: |
182 | 198 | case NPL_VT_MEMBER: |
183 | 199 | case NPL_VT_STATE: |
200 | + case NPL_VT_S: | |
201 | + case NPL_VT_VS: | |
184 | 202 | case NPL_VT_STACK: |
185 | 203 | case NPL_VT_Q: |
204 | + case NPL_VT_VQ: | |
205 | + case NPL_VT_QUEUE: | |
186 | 206 | case NPL_VT_TQ: |
187 | 207 | case NPL_VT_STREAM: |
188 | 208 | if (val->object == NULL) |
@@ -367,6 +387,16 @@ | ||
367 | 387 | _set_object(val, NPL_VT_STATE, NPL_OBJECT(state)); |
368 | 388 | } |
369 | 389 | |
390 | +void npl_val_set_s(npl_val_t *val, npl_s_t *s) | |
391 | +{ | |
392 | + _set_object(val, NPL_VT_S, NPL_OBJECT(s)); | |
393 | +} | |
394 | + | |
395 | +void npl_val_set_vs(npl_val_t *val, npl_vs_t *vs) | |
396 | +{ | |
397 | + _set_object(val, NPL_VT_VS, NPL_OBJECT(vs)); | |
398 | +} | |
399 | + | |
370 | 400 | void npl_val_set_stack(npl_val_t *val, npl_stack_t *stack) |
371 | 401 | { |
372 | 402 | _set_object(val, NPL_VT_STACK, NPL_OBJECT(stack)); |
@@ -377,6 +407,16 @@ | ||
377 | 407 | _set_object(val, NPL_VT_Q, NPL_OBJECT(q)); |
378 | 408 | } |
379 | 409 | |
410 | +void npl_val_set_vq(npl_val_t *val, npl_vq_t *vq) | |
411 | +{ | |
412 | + _set_object(val, NPL_VT_VQ, NPL_OBJECT(vq)); | |
413 | +} | |
414 | + | |
415 | +void npl_val_set_queue(npl_val_t *val, npl_queue_t *queue) | |
416 | +{ | |
417 | + _set_object(val, NPL_VT_QUEUE, NPL_OBJECT(queue)); | |
418 | +} | |
419 | + | |
380 | 420 | void npl_val_set_tq(npl_val_t *val, npl_tq_t *tq) |
381 | 421 | { |
382 | 422 | _set_object(val, NPL_VT_TQ, NPL_OBJECT(tq)); |
@@ -53,7 +53,7 @@ | ||
53 | 53 | |
54 | 54 | // var 内部の val への参照を返す。 |
55 | 55 | // (勝手に npl_val_end() で終了してはいけない) |
56 | -npl_val_t* npl_var_ref(npl_var_t *var) | |
56 | +npl_val_t* npl_var_ret(npl_var_t *var) | |
57 | 57 | { |
58 | 58 | assert(var); |
59 | 59 | return &var->val; |
@@ -0,0 +1,152 @@ | ||
1 | +#include "global.h" | |
2 | + | |
3 | +static int _init(npl_vq_t *vq) | |
4 | +{ | |
5 | + npl_val_t *v = vq->q.chunk.chunk; | |
6 | + size_t i; | |
7 | + | |
8 | + for (i=0; i < vq->q.len; i++) | |
9 | + npl_val_begin(v + i); | |
10 | + return 0; | |
11 | +} | |
12 | + | |
13 | +static void _final(npl_vq_t *vq) | |
14 | +{ | |
15 | + npl_val_t *v = vq->q.chunk.chunk; | |
16 | + size_t i; | |
17 | + | |
18 | + for (i=0; i < vq->q.len; i++) | |
19 | + npl_val_end(v + i); | |
20 | +} | |
21 | + | |
22 | +static void _cleaner(void *data) | |
23 | +{ | |
24 | + npl_val_t *val = data; | |
25 | + | |
26 | + npl_val_set_null(val); | |
27 | +} | |
28 | + | |
29 | +npl_vq_t* npl_vq_alloc(npl_type_t *type, size_t len) | |
30 | +{ | |
31 | + npl_vq_t *vq; | |
32 | + | |
33 | + assert(type); | |
34 | + assert(npl_type_check(npl_vq_type, type) == 0); | |
35 | + | |
36 | + vq = NPL_VQ(npl_q_alloc(type, sizeof(npl_val_t), len)); | |
37 | + if (vq == NULL) | |
38 | + return NULL; | |
39 | + vq->q.cleaner = _cleaner; | |
40 | + if (_init(vq)) { | |
41 | + npl_object_unref(NPL_OBJECT(vq)); | |
42 | + return NULL; | |
43 | + } | |
44 | + | |
45 | + return vq; | |
46 | +} | |
47 | + | |
48 | +npl_vq_t* npl_vq_new(size_t len) | |
49 | +{ | |
50 | + return npl_vq_alloc(npl_vq_type, len); | |
51 | +} | |
52 | + | |
53 | +size_t npl_vq_len(npl_vq_t *vq) | |
54 | +{ | |
55 | + assert(vq); | |
56 | + return npl_q_len(&vq->q); | |
57 | +} | |
58 | + | |
59 | +int npl_vq_is_full(npl_vq_t *vq) | |
60 | +{ | |
61 | + assert(vq); | |
62 | + return npl_q_is_full(&vq->q); | |
63 | +} | |
64 | + | |
65 | +int npl_vq_is_empty(npl_vq_t *vq) | |
66 | +{ | |
67 | + assert(vq); | |
68 | + return npl_q_is_empty(&vq->q); | |
69 | +} | |
70 | + | |
71 | +void npl_vq_empty(npl_vq_t *vq) | |
72 | +{ | |
73 | + assert(vq); | |
74 | + return npl_q_empty(&vq->q); | |
75 | +} | |
76 | + | |
77 | +size_t npl_vq_count(npl_vq_t *vq) | |
78 | +{ | |
79 | + assert(vq); | |
80 | + return npl_q_count(&vq->q); | |
81 | +} | |
82 | + | |
83 | +int npl_vq_push(npl_vq_t *vq, npl_val_t *val) | |
84 | +{ | |
85 | + npl_val_t *v; | |
86 | + | |
87 | + assert(vq); | |
88 | + | |
89 | + v = npl_q_push(&vq->q); | |
90 | + if (v == NULL) | |
91 | + return 1; // error | |
92 | + if (val == NULL) | |
93 | + npl_val_copy(v, val); | |
94 | + return 0; | |
95 | +} | |
96 | + | |
97 | +int npl_vq_pop(npl_vq_t *vq, npl_val_t *val_r) | |
98 | +{ | |
99 | + assert(vq); | |
100 | + | |
101 | + if (npl_vq_get(vq, 0, val_r)) | |
102 | + return 1; // error | |
103 | + npl_vq_remove(vq, 1); | |
104 | + return 0; | |
105 | +} | |
106 | + | |
107 | +int npl_vq_get(npl_vq_t *vq, size_t n, npl_val_t *val_r) | |
108 | +{ | |
109 | + npl_val_t *v; | |
110 | + | |
111 | + assert(vq); | |
112 | + | |
113 | + v = npl_q_ret(&vq->q, n); | |
114 | + if (v == NULL) | |
115 | + return 1; // error | |
116 | + if (val_r == NULL) | |
117 | + npl_val_copy(val_r, v); | |
118 | + return 0; | |
119 | +} | |
120 | + | |
121 | +npl_val_t* npl_vq_ret(npl_vq_t *vq, size_t n) | |
122 | +{ | |
123 | + assert(vq); | |
124 | + return npl_q_ret(&vq->q, n); | |
125 | +} | |
126 | + | |
127 | +void npl_vq_remove(npl_vq_t *vq, size_t n) | |
128 | +{ | |
129 | + assert(vq); | |
130 | + npl_q_remove(&vq->q, n); | |
131 | +} | |
132 | + | |
133 | +static void _destructor(npl_object_t *object) | |
134 | +{ | |
135 | + _final(NPL_VQ(object)); | |
136 | +} | |
137 | + | |
138 | +// vq クラスの型情報 | |
139 | +npl_type_t _npl_vq_type = { | |
140 | + .object = { | |
141 | + .type = &_npl_type_type, | |
142 | + .ref_count = 0, | |
143 | + .static_flag = 1, | |
144 | + }, | |
145 | + .name = L"vq", | |
146 | + .destructor = _destructor, | |
147 | + .parent = &_npl_q_type, | |
148 | + .size = sizeof(npl_vq_t), | |
149 | +}; | |
150 | + | |
151 | +npl_type_t *npl_vq_type = &_npl_vq_type; | |
152 | + |
@@ -0,0 +1,136 @@ | ||
1 | +#include "global.h" | |
2 | + | |
3 | +static void _cleaner(void *data) | |
4 | +{ | |
5 | + npl_val_t *val = data; | |
6 | + | |
7 | + npl_val_end(val); | |
8 | +} | |
9 | + | |
10 | +int npl_vs_init(npl_vs_t *vs) | |
11 | +{ | |
12 | + assert(vs); | |
13 | + | |
14 | + if (npl_s_init(&vs->s, sizeof(npl_val_t))) | |
15 | + return 1; // error | |
16 | + vs->s.cleaner = _cleaner; | |
17 | + return 0; | |
18 | +} | |
19 | + | |
20 | +npl_vs_t* npl_vs_new(void) | |
21 | +{ | |
22 | + npl_vs_t *vs; | |
23 | + | |
24 | + vs = NPL_VS(npl_object_alloc(npl_vs_type)); | |
25 | + if (vs == NULL) | |
26 | + return NULL; | |
27 | + if (npl_vs_init(vs)) { | |
28 | + npl_object_unref(NPL_OBJECT(vs)); | |
29 | + return NULL; | |
30 | + } | |
31 | + | |
32 | + return vs; | |
33 | +} | |
34 | + | |
35 | +size_t npl_vs_count(npl_vs_t *vs) | |
36 | +{ | |
37 | + assert(vs); | |
38 | + return npl_s_count(&vs->s); | |
39 | +} | |
40 | + | |
41 | +size_t npl_vs_len(npl_vs_t *vs) | |
42 | +{ | |
43 | + assert(vs); | |
44 | + return npl_s_len(&vs->s); | |
45 | +} | |
46 | + | |
47 | +int npl_vs_enter(npl_vs_t *vs) | |
48 | +{ | |
49 | + assert(vs); | |
50 | + return npl_s_enter(&vs->s); | |
51 | +} | |
52 | + | |
53 | +int npl_vs_leave(npl_vs_t *vs) | |
54 | +{ | |
55 | + assert(vs); | |
56 | + return npl_s_leave(&vs->s); | |
57 | +} | |
58 | + | |
59 | +int npl_vs_is_empty(npl_vs_t *vs) | |
60 | +{ | |
61 | + assert(vs); | |
62 | + return npl_s_is_empty(&vs->s); | |
63 | +} | |
64 | + | |
65 | +void npl_vs_empty(npl_vs_t *vs) | |
66 | +{ | |
67 | + assert(vs); | |
68 | + return npl_s_empty(&vs->s); | |
69 | +} | |
70 | + | |
71 | +int npl_vs_push(npl_vs_t *vs, npl_val_t *val) | |
72 | +{ | |
73 | + npl_val_t *v; | |
74 | + | |
75 | + assert(vs); | |
76 | + | |
77 | + v = npl_s_push(&vs->s); | |
78 | + if (v == NULL) | |
79 | + return 1; // error | |
80 | + npl_val_begin(v); | |
81 | + if (val != NULL) | |
82 | + npl_val_copy(v, val); | |
83 | + | |
84 | + return 0; | |
85 | +} | |
86 | + | |
87 | +int npl_vs_pop(npl_vs_t *vs, npl_val_t *val_r) | |
88 | +{ | |
89 | + return npl_vs_get(vs, 0, val_r); | |
90 | +} | |
91 | + | |
92 | +int npl_vs_get(npl_vs_t *vs, size_t n, npl_val_t *val_r) | |
93 | +{ | |
94 | + npl_val_t *v; | |
95 | + | |
96 | + assert(vs); | |
97 | + | |
98 | + v = npl_s_ret(&vs->s, n); | |
99 | + if (v == NULL) | |
100 | + return 1; // error | |
101 | + if (val_r != NULL) | |
102 | + npl_val_copy(val_r, v); | |
103 | + npl_vs_remove(vs, 1); | |
104 | + | |
105 | + return 0; | |
106 | +} | |
107 | + | |
108 | +npl_val_t* npl_vs_ret(npl_vs_t *vs, size_t n) | |
109 | +{ | |
110 | + assert(vs); | |
111 | + return npl_s_ret(&vs->s, n); | |
112 | +} | |
113 | + | |
114 | +void npl_vs_remove(npl_vs_t *vs, size_t n) | |
115 | +{ | |
116 | + size_t i; | |
117 | + | |
118 | + assert(vs); | |
119 | + npl_s_remove(&vs->s, n); | |
120 | +} | |
121 | + | |
122 | +// vs クラスの型情報 | |
123 | +npl_type_t _npl_vs_type = { | |
124 | + .object = { | |
125 | + .type = &_npl_type_type, | |
126 | + .ref_count = 0, | |
127 | + .static_flag = 1, | |
128 | + }, | |
129 | + .name = L"vs", | |
130 | + .destructor = NULL, | |
131 | + .parent = &_npl_s_type, | |
132 | + .size = sizeof(npl_vs_t), | |
133 | +}; | |
134 | + | |
135 | +npl_type_t *npl_vs_type = &_npl_vs_type; | |
136 | + |