revert-mm-fix-blkdev-size-calculation-in-generic_write_checks
[linux-2.6/linux-trees-mm.git] / fs / reiser4 / coord.c
blobd171786ed36ad6106944b09336afadef9ec613d3
1 /* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by reiser4/README */
3 #include "forward.h"
4 #include "debug.h"
5 #include "dformat.h"
6 #include "tree.h"
7 #include "plugin/item/item.h"
8 #include "znode.h"
9 #include "coord.h"
11 /* Internal constructor. */
12 static inline void
13 coord_init_values(coord_t * coord, const znode * node, pos_in_node_t item_pos,
14 pos_in_node_t unit_pos, between_enum between)
16 coord->node = (znode *) node;
17 coord_set_item_pos(coord, item_pos);
18 coord->unit_pos = unit_pos;
19 coord->between = between;
20 ON_DEBUG(coord->plug_v = 0);
21 ON_DEBUG(coord->body_v = 0);
23 /*ON_TRACE (TRACE_COORDS, "init coord %p node %p: %u %u %s\n", coord, node, item_pos, unit_pos, coord_tween_tostring (between)); */
26 /* after shifting of node content, coord previously set properly may become
27 invalid, try to "normalize" it. */
28 void coord_normalize(coord_t * coord)
30 znode *node;
32 node = coord->node;
33 assert("vs-683", node);
35 coord_clear_iplug(coord);
37 if (node_is_empty(node)) {
38 coord_init_first_unit(coord, node);
39 } else if ((coord->between == AFTER_ITEM)
40 || (coord->between == AFTER_UNIT)) {
41 return;
42 } else if (coord->item_pos == coord_num_items(coord)
43 && coord->between == BEFORE_ITEM) {
44 coord_dec_item_pos(coord);
45 coord->between = AFTER_ITEM;
46 } else if (coord->unit_pos == coord_num_units(coord)
47 && coord->between == BEFORE_UNIT) {
48 coord->unit_pos--;
49 coord->between = AFTER_UNIT;
50 } else if (coord->item_pos == coord_num_items(coord)
51 && coord->unit_pos == 0 && coord->between == BEFORE_UNIT) {
52 coord_dec_item_pos(coord);
53 coord->unit_pos = 0;
54 coord->between = AFTER_ITEM;
58 /* Copy a coordinate. */
59 void coord_dup(coord_t * coord, const coord_t * old_coord)
61 assert("jmacd-9800", coord_check(old_coord));
62 coord_dup_nocheck(coord, old_coord);
65 /* Copy a coordinate without check. Useful when old_coord->node is not
66 loaded. As in cbk_tree_lookup -> connect_znode -> connect_one_side */
67 void coord_dup_nocheck(coord_t * coord, const coord_t * old_coord)
69 coord->node = old_coord->node;
70 coord_set_item_pos(coord, old_coord->item_pos);
71 coord->unit_pos = old_coord->unit_pos;
72 coord->between = old_coord->between;
73 coord->iplugid = old_coord->iplugid;
74 ON_DEBUG(coord->plug_v = old_coord->plug_v);
75 ON_DEBUG(coord->body_v = old_coord->body_v);
78 /* Initialize an invalid coordinate. */
79 void coord_init_invalid(coord_t * coord, const znode * node)
81 coord_init_values(coord, node, 0, 0, INVALID_COORD);
84 void coord_init_first_unit_nocheck(coord_t * coord, const znode * node)
86 coord_init_values(coord, node, 0, 0, AT_UNIT);
89 /* Initialize a coordinate to point at the first unit of the first item. If the node is
90 empty, it is positioned at the EMPTY_NODE. */
91 void coord_init_first_unit(coord_t * coord, const znode * node)
93 int is_empty = node_is_empty(node);
95 coord_init_values(coord, node, 0, 0, (is_empty ? EMPTY_NODE : AT_UNIT));
97 assert("jmacd-9801", coord_check(coord));
100 /* Initialize a coordinate to point at the last unit of the last item. If the node is
101 empty, it is positioned at the EMPTY_NODE. */
102 void coord_init_last_unit(coord_t * coord, const znode * node)
104 int is_empty = node_is_empty(node);
106 coord_init_values(coord, node,
107 (is_empty ? 0 : node_num_items(node) - 1), 0,
108 (is_empty ? EMPTY_NODE : AT_UNIT));
109 if (!is_empty)
110 coord->unit_pos = coord_last_unit_pos(coord);
111 assert("jmacd-9802", coord_check(coord));
114 /* Initialize a coordinate to before the first item. If the node is empty, it is
115 positioned at the EMPTY_NODE. */
116 void coord_init_before_first_item(coord_t * coord, const znode * node)
118 int is_empty = node_is_empty(node);
120 coord_init_values(coord, node, 0, 0,
121 (is_empty ? EMPTY_NODE : BEFORE_UNIT));
123 assert("jmacd-9803", coord_check(coord));
126 /* Initialize a coordinate to after the last item. If the node is empty, it is positioned
127 at the EMPTY_NODE. */
128 void coord_init_after_last_item(coord_t * coord, const znode * node)
130 int is_empty = node_is_empty(node);
132 coord_init_values(coord, node,
133 (is_empty ? 0 : node_num_items(node) - 1), 0,
134 (is_empty ? EMPTY_NODE : AFTER_ITEM));
136 assert("jmacd-9804", coord_check(coord));
139 /* Initialize a coordinate to after last unit in the item. Coord must be set
140 already to existing item */
141 void coord_init_after_item_end(coord_t * coord)
143 coord->between = AFTER_UNIT;
144 coord->unit_pos = coord_last_unit_pos(coord);
147 /* Initialize a coordinate to before the item. Coord must be set already to existing item */
148 void coord_init_before_item(coord_t * coord)
150 coord->unit_pos = 0;
151 coord->between = BEFORE_ITEM;
154 /* Initialize a coordinate to after the item. Coord must be set already to existing item */
155 void coord_init_after_item(coord_t * coord)
157 coord->unit_pos = 0;
158 coord->between = AFTER_ITEM;
161 /* Initialize a coordinate by 0s. Used in places where init_coord was used and
162 it was not clear how actually */
163 void coord_init_zero(coord_t * coord)
165 memset(coord, 0, sizeof(*coord));
168 /* Return the number of units at the present item. Asserts coord_is_existing_item(). */
169 unsigned coord_num_units(const coord_t * coord)
171 assert("jmacd-9806", coord_is_existing_item(coord));
173 return item_plugin_by_coord(coord)->b.nr_units(coord);
176 /* Returns true if the coord was initializewd by coord_init_invalid (). */
177 /* Audited by: green(2002.06.15) */
178 int coord_is_invalid(const coord_t * coord)
180 return coord->between == INVALID_COORD;
183 /* Returns true if the coordinate is positioned at an existing item, not before or after
184 an item. It may be placed at, before, or after any unit within the item, whether
185 existing or not. */
186 int coord_is_existing_item(const coord_t * coord)
188 switch (coord->between) {
189 case EMPTY_NODE:
190 case BEFORE_ITEM:
191 case AFTER_ITEM:
192 case INVALID_COORD:
193 return 0;
195 case BEFORE_UNIT:
196 case AT_UNIT:
197 case AFTER_UNIT:
198 return coord->item_pos < coord_num_items(coord);
201 impossible("jmacd-9900", "unreachable coord: %p", coord);
202 return 0;
205 /* Returns true if the coordinate is positioned at an existing unit, not before or after a
206 unit. */
207 /* Audited by: green(2002.06.15) */
208 int coord_is_existing_unit(const coord_t * coord)
210 switch (coord->between) {
211 case EMPTY_NODE:
212 case BEFORE_UNIT:
213 case AFTER_UNIT:
214 case BEFORE_ITEM:
215 case AFTER_ITEM:
216 case INVALID_COORD:
217 return 0;
219 case AT_UNIT:
220 return (coord->item_pos < coord_num_items(coord)
221 && coord->unit_pos < coord_num_units(coord));
224 impossible("jmacd-9902", "unreachable");
225 return 0;
228 /* Returns true if the coordinate is positioned at the first unit of the first item. Not
229 true for empty nodes nor coordinates positioned before the first item. */
230 /* Audited by: green(2002.06.15) */
231 int coord_is_leftmost_unit(const coord_t * coord)
233 return (coord->between == AT_UNIT && coord->item_pos == 0
234 && coord->unit_pos == 0);
237 #if REISER4_DEBUG
238 /* For assertions only, checks for a valid coordinate. */
239 int coord_check(const coord_t * coord)
241 if (coord->node == NULL) {
242 return 0;
244 if (znode_above_root(coord->node))
245 return 1;
247 switch (coord->between) {
248 default:
249 case INVALID_COORD:
250 return 0;
251 case EMPTY_NODE:
252 if (!node_is_empty(coord->node)) {
253 return 0;
255 return coord->item_pos == 0 && coord->unit_pos == 0;
257 case BEFORE_UNIT:
258 case AFTER_UNIT:
259 if (node_is_empty(coord->node) && (coord->item_pos == 0)
260 && (coord->unit_pos == 0))
261 return 1;
262 case AT_UNIT:
263 break;
264 case AFTER_ITEM:
265 case BEFORE_ITEM:
266 /* before/after item should not set unit_pos. */
267 if (coord->unit_pos != 0) {
268 return 0;
270 break;
273 if (coord->item_pos >= node_num_items(coord->node)) {
274 return 0;
277 /* FIXME-VS: we are going to check unit_pos. This makes no sense when
278 between is set either AFTER_ITEM or BEFORE_ITEM */
279 if (coord->between == AFTER_ITEM || coord->between == BEFORE_ITEM)
280 return 1;
282 if (coord_is_iplug_set(coord) &&
283 coord->unit_pos >
284 item_plugin_by_coord(coord)->b.nr_units(coord) - 1) {
285 return 0;
287 return 1;
289 #endif
291 /* Adjust coordinate boundaries based on the number of items prior to coord_next/prev.
292 Returns 1 if the new position is does not exist. */
293 static int coord_adjust_items(coord_t * coord, unsigned items, int is_next)
295 /* If the node is invalid, leave it. */
296 if (coord->between == INVALID_COORD) {
297 return 1;
300 /* If the node is empty, set it appropriately. */
301 if (items == 0) {
302 coord->between = EMPTY_NODE;
303 coord_set_item_pos(coord, 0);
304 coord->unit_pos = 0;
305 return 1;
308 /* If it was empty and it no longer is, set to BEFORE/AFTER_ITEM. */
309 if (coord->between == EMPTY_NODE) {
310 coord->between = (is_next ? BEFORE_ITEM : AFTER_ITEM);
311 coord_set_item_pos(coord, 0);
312 coord->unit_pos = 0;
313 return 0;
316 /* If the item_pos is out-of-range, set it appropriatly. */
317 if (coord->item_pos >= items) {
318 coord->between = AFTER_ITEM;
319 coord_set_item_pos(coord, items - 1);
320 coord->unit_pos = 0;
321 /* If is_next, return 1 (can't go any further). */
322 return is_next;
325 return 0;
328 /* Advances the coordinate by one unit to the right. If empty, no change. If
329 coord_is_rightmost_unit, advances to AFTER THE LAST ITEM. Returns 0 if new position is an
330 existing unit. */
331 int coord_next_unit(coord_t * coord)
333 unsigned items = coord_num_items(coord);
335 if (coord_adjust_items(coord, items, 1) == 1) {
336 return 1;
339 switch (coord->between) {
340 case BEFORE_UNIT:
341 /* Now it is positioned at the same unit. */
342 coord->between = AT_UNIT;
343 return 0;
345 case AFTER_UNIT:
346 case AT_UNIT:
347 /* If it was at or after a unit and there are more units in this item,
348 advance to the next one. */
349 if (coord->unit_pos < coord_last_unit_pos(coord)) {
350 coord->unit_pos += 1;
351 coord->between = AT_UNIT;
352 return 0;
355 /* Otherwise, it is crossing an item boundary and treated as if it was
356 after the current item. */
357 coord->between = AFTER_ITEM;
358 coord->unit_pos = 0;
359 /* FALLTHROUGH */
361 case AFTER_ITEM:
362 /* Check for end-of-node. */
363 if (coord->item_pos == items - 1) {
364 return 1;
367 coord_inc_item_pos(coord);
368 coord->unit_pos = 0;
369 coord->between = AT_UNIT;
370 return 0;
372 case BEFORE_ITEM:
373 /* The adjust_items checks ensure that we are valid here. */
374 coord->unit_pos = 0;
375 coord->between = AT_UNIT;
376 return 0;
378 case INVALID_COORD:
379 case EMPTY_NODE:
380 /* Handled in coord_adjust_items(). */
381 break;
384 impossible("jmacd-9902", "unreachable");
385 return 0;
388 /* Advances the coordinate by one item to the right. If empty, no change. If
389 coord_is_rightmost_unit, advances to AFTER THE LAST ITEM. Returns 0 if new position is
390 an existing item. */
391 int coord_next_item(coord_t * coord)
393 unsigned items = coord_num_items(coord);
395 if (coord_adjust_items(coord, items, 1) == 1) {
396 return 1;
399 switch (coord->between) {
400 case AFTER_UNIT:
401 case AT_UNIT:
402 case BEFORE_UNIT:
403 case AFTER_ITEM:
404 /* Check for end-of-node. */
405 if (coord->item_pos == items - 1) {
406 coord->between = AFTER_ITEM;
407 coord->unit_pos = 0;
408 coord_clear_iplug(coord);
409 return 1;
412 /* Anywhere in an item, go to the next one. */
413 coord->between = AT_UNIT;
414 coord_inc_item_pos(coord);
415 coord->unit_pos = 0;
416 return 0;
418 case BEFORE_ITEM:
419 /* The out-of-range check ensures that we are valid here. */
420 coord->unit_pos = 0;
421 coord->between = AT_UNIT;
422 return 0;
423 case INVALID_COORD:
424 case EMPTY_NODE:
425 /* Handled in coord_adjust_items(). */
426 break;
429 impossible("jmacd-9903", "unreachable");
430 return 0;
433 /* Advances the coordinate by one unit to the left. If empty, no change. If
434 coord_is_leftmost_unit, advances to BEFORE THE FIRST ITEM. Returns 0 if new position
435 is an existing unit. */
436 int coord_prev_unit(coord_t * coord)
438 unsigned items = coord_num_items(coord);
440 if (coord_adjust_items(coord, items, 0) == 1) {
441 return 1;
444 switch (coord->between) {
445 case AT_UNIT:
446 case BEFORE_UNIT:
447 if (coord->unit_pos > 0) {
448 coord->unit_pos -= 1;
449 coord->between = AT_UNIT;
450 return 0;
453 if (coord->item_pos == 0) {
454 coord->between = BEFORE_ITEM;
455 return 1;
458 coord_dec_item_pos(coord);
459 coord->unit_pos = coord_last_unit_pos(coord);
460 coord->between = AT_UNIT;
461 return 0;
463 case AFTER_UNIT:
464 /* What if unit_pos is out-of-range? */
465 assert("jmacd-5442",
466 coord->unit_pos <= coord_last_unit_pos(coord));
467 coord->between = AT_UNIT;
468 return 0;
470 case BEFORE_ITEM:
471 if (coord->item_pos == 0) {
472 return 1;
475 coord_dec_item_pos(coord);
476 /* FALLTHROUGH */
478 case AFTER_ITEM:
479 coord->between = AT_UNIT;
480 coord->unit_pos = coord_last_unit_pos(coord);
481 return 0;
483 case INVALID_COORD:
484 case EMPTY_NODE:
485 break;
488 impossible("jmacd-9904", "unreachable");
489 return 0;
492 /* Advances the coordinate by one item to the left. If empty, no change. If
493 coord_is_leftmost_unit, advances to BEFORE THE FIRST ITEM. Returns 0 if new position
494 is an existing item. */
495 int coord_prev_item(coord_t * coord)
497 unsigned items = coord_num_items(coord);
499 if (coord_adjust_items(coord, items, 0) == 1) {
500 return 1;
503 switch (coord->between) {
504 case AT_UNIT:
505 case AFTER_UNIT:
506 case BEFORE_UNIT:
507 case BEFORE_ITEM:
509 if (coord->item_pos == 0) {
510 coord->between = BEFORE_ITEM;
511 coord->unit_pos = 0;
512 return 1;
515 coord_dec_item_pos(coord);
516 coord->unit_pos = 0;
517 coord->between = AT_UNIT;
518 return 0;
520 case AFTER_ITEM:
521 coord->between = AT_UNIT;
522 coord->unit_pos = 0;
523 return 0;
525 case INVALID_COORD:
526 case EMPTY_NODE:
527 break;
530 impossible("jmacd-9905", "unreachable");
531 return 0;
534 /* Calls either coord_init_first_unit or coord_init_last_unit depending on sideof argument. */
535 void coord_init_sideof_unit(coord_t * coord, const znode * node, sideof dir)
537 assert("jmacd-9821", dir == LEFT_SIDE || dir == RIGHT_SIDE);
538 if (dir == LEFT_SIDE) {
539 coord_init_first_unit(coord, node);
540 } else {
541 coord_init_last_unit(coord, node);
545 /* Calls either coord_is_before_leftmost or coord_is_after_rightmost depending on sideof
546 argument. */
547 /* Audited by: green(2002.06.15) */
548 int coord_is_after_sideof_unit(coord_t * coord, sideof dir)
550 assert("jmacd-9822", dir == LEFT_SIDE || dir == RIGHT_SIDE);
551 if (dir == LEFT_SIDE) {
552 return coord_is_before_leftmost(coord);
553 } else {
554 return coord_is_after_rightmost(coord);
558 /* Calls either coord_next_unit or coord_prev_unit depending on sideof argument. */
559 /* Audited by: green(2002.06.15) */
560 int coord_sideof_unit(coord_t * coord, sideof dir)
562 assert("jmacd-9823", dir == LEFT_SIDE || dir == RIGHT_SIDE);
563 if (dir == LEFT_SIDE) {
564 return coord_prev_unit(coord);
565 } else {
566 return coord_next_unit(coord);
570 #if REISER4_DEBUG
571 int coords_equal(const coord_t * c1, const coord_t * c2)
573 assert("nikita-2840", c1 != NULL);
574 assert("nikita-2841", c2 != NULL);
576 return
577 c1->node == c2->node &&
578 c1->item_pos == c2->item_pos &&
579 c1->unit_pos == c2->unit_pos && c1->between == c2->between;
581 #endif /* REISER4_DEBUG */
583 /* If coord_is_after_rightmost return NCOORD_ON_THE_RIGHT, if coord_is_after_leftmost
584 return NCOORD_ON_THE_LEFT, otherwise return NCOORD_INSIDE. */
585 /* Audited by: green(2002.06.15) */
586 coord_wrt_node coord_wrt(const coord_t * coord)
588 if (coord_is_before_leftmost(coord)) {
589 return COORD_ON_THE_LEFT;
592 if (coord_is_after_rightmost(coord)) {
593 return COORD_ON_THE_RIGHT;
596 return COORD_INSIDE;
599 /* Returns true if the coordinate is positioned after the last item or after the last unit
600 of the last item or it is an empty node. */
601 /* Audited by: green(2002.06.15) */
602 int coord_is_after_rightmost(const coord_t * coord)
604 assert("jmacd-7313", coord_check(coord));
606 switch (coord->between) {
607 case INVALID_COORD:
608 case AT_UNIT:
609 case BEFORE_UNIT:
610 case BEFORE_ITEM:
611 return 0;
613 case EMPTY_NODE:
614 return 1;
616 case AFTER_ITEM:
617 return (coord->item_pos == node_num_items(coord->node) - 1);
619 case AFTER_UNIT:
620 return ((coord->item_pos == node_num_items(coord->node) - 1) &&
621 coord->unit_pos == coord_last_unit_pos(coord));
624 impossible("jmacd-9908", "unreachable");
625 return 0;
628 /* Returns true if the coordinate is positioned before the first item or it is an empty
629 node. */
630 int coord_is_before_leftmost(const coord_t * coord)
632 /* FIXME-VS: coord_check requires node to be loaded whereas it is not
633 necessary to check if coord is set before leftmost
634 assert ("jmacd-7313", coord_check (coord)); */
635 switch (coord->between) {
636 case INVALID_COORD:
637 case AT_UNIT:
638 case AFTER_ITEM:
639 case AFTER_UNIT:
640 return 0;
642 case EMPTY_NODE:
643 return 1;
645 case BEFORE_ITEM:
646 case BEFORE_UNIT:
647 return (coord->item_pos == 0) && (coord->unit_pos == 0);
650 impossible("jmacd-9908", "unreachable");
651 return 0;
654 /* Returns true if the coordinate is positioned after a item, before a item, after the
655 last unit of an item, before the first unit of an item, or at an empty node. */
656 /* Audited by: green(2002.06.15) */
657 int coord_is_between_items(const coord_t * coord)
659 assert("jmacd-7313", coord_check(coord));
661 switch (coord->between) {
662 case INVALID_COORD:
663 case AT_UNIT:
664 return 0;
666 case AFTER_ITEM:
667 case BEFORE_ITEM:
668 case EMPTY_NODE:
669 return 1;
671 case BEFORE_UNIT:
672 return coord->unit_pos == 0;
674 case AFTER_UNIT:
675 return coord->unit_pos == coord_last_unit_pos(coord);
678 impossible("jmacd-9908", "unreachable");
679 return 0;
682 #if REISER4_DEBUG
683 /* Returns true if the coordinates are positioned at adjacent units, regardless of
684 before-after or item boundaries. */
685 int coord_are_neighbors(coord_t * c1, coord_t * c2)
687 coord_t *left;
688 coord_t *right;
690 assert("nikita-1241", c1 != NULL);
691 assert("nikita-1242", c2 != NULL);
692 assert("nikita-1243", c1->node == c2->node);
693 assert("nikita-1244", coord_is_existing_unit(c1));
694 assert("nikita-1245", coord_is_existing_unit(c2));
696 left = right = NULL;
697 switch (coord_compare(c1, c2)) {
698 case COORD_CMP_ON_LEFT:
699 left = c1;
700 right = c2;
701 break;
702 case COORD_CMP_ON_RIGHT:
703 left = c2;
704 right = c1;
705 break;
706 case COORD_CMP_SAME:
707 return 0;
708 default:
709 wrong_return_value("nikita-1246", "compare_coords()");
711 assert("vs-731", left && right);
712 if (left->item_pos == right->item_pos) {
713 return left->unit_pos + 1 == right->unit_pos;
714 } else if (left->item_pos + 1 == right->item_pos) {
715 return (left->unit_pos == coord_last_unit_pos(left))
716 && (right->unit_pos == 0);
717 } else {
718 return 0;
721 #endif /* REISER4_DEBUG */
723 /* Assuming two coordinates are positioned in the same node, return COORD_CMP_ON_RIGHT,
724 COORD_CMP_ON_LEFT, or COORD_CMP_SAME depending on c1's position relative to c2. */
725 /* Audited by: green(2002.06.15) */
726 coord_cmp coord_compare(coord_t * c1, coord_t * c2)
728 assert("vs-209", c1->node == c2->node);
729 assert("vs-194", coord_is_existing_unit(c1)
730 && coord_is_existing_unit(c2));
732 if (c1->item_pos > c2->item_pos)
733 return COORD_CMP_ON_RIGHT;
734 if (c1->item_pos < c2->item_pos)
735 return COORD_CMP_ON_LEFT;
736 if (c1->unit_pos > c2->unit_pos)
737 return COORD_CMP_ON_RIGHT;
738 if (c1->unit_pos < c2->unit_pos)
739 return COORD_CMP_ON_LEFT;
740 return COORD_CMP_SAME;
743 /* If the coordinate is between items, shifts it to the right. Returns 0 on success and
744 non-zero if there is no position to the right. */
745 int coord_set_to_right(coord_t * coord)
747 unsigned items = coord_num_items(coord);
749 if (coord_adjust_items(coord, items, 1) == 1) {
750 return 1;
753 switch (coord->between) {
754 case AT_UNIT:
755 return 0;
757 case BEFORE_ITEM:
758 case BEFORE_UNIT:
759 coord->between = AT_UNIT;
760 return 0;
762 case AFTER_UNIT:
763 if (coord->unit_pos < coord_last_unit_pos(coord)) {
764 coord->unit_pos += 1;
765 coord->between = AT_UNIT;
766 return 0;
767 } else {
769 coord->unit_pos = 0;
771 if (coord->item_pos == items - 1) {
772 coord->between = AFTER_ITEM;
773 return 1;
776 coord_inc_item_pos(coord);
777 coord->between = AT_UNIT;
778 return 0;
781 case AFTER_ITEM:
782 if (coord->item_pos == items - 1) {
783 return 1;
786 coord_inc_item_pos(coord);
787 coord->unit_pos = 0;
788 coord->between = AT_UNIT;
789 return 0;
791 case EMPTY_NODE:
792 return 1;
794 case INVALID_COORD:
795 break;
798 impossible("jmacd-9920", "unreachable");
799 return 0;
802 /* If the coordinate is between items, shifts it to the left. Returns 0 on success and
803 non-zero if there is no position to the left. */
804 int coord_set_to_left(coord_t * coord)
806 unsigned items = coord_num_items(coord);
808 if (coord_adjust_items(coord, items, 0) == 1) {
809 return 1;
812 switch (coord->between) {
813 case AT_UNIT:
814 return 0;
816 case AFTER_UNIT:
817 coord->between = AT_UNIT;
818 return 0;
820 case AFTER_ITEM:
821 coord->between = AT_UNIT;
822 coord->unit_pos = coord_last_unit_pos(coord);
823 return 0;
825 case BEFORE_UNIT:
826 if (coord->unit_pos > 0) {
827 coord->unit_pos -= 1;
828 coord->between = AT_UNIT;
829 return 0;
830 } else {
832 if (coord->item_pos == 0) {
833 coord->between = BEFORE_ITEM;
834 return 1;
837 coord->unit_pos = coord_last_unit_pos(coord);
838 coord_dec_item_pos(coord);
839 coord->between = AT_UNIT;
840 return 0;
843 case BEFORE_ITEM:
844 if (coord->item_pos == 0) {
845 return 1;
848 coord_dec_item_pos(coord);
849 coord->unit_pos = coord_last_unit_pos(coord);
850 coord->between = AT_UNIT;
851 return 0;
853 case EMPTY_NODE:
854 return 1;
856 case INVALID_COORD:
857 break;
860 impossible("jmacd-9920", "unreachable");
861 return 0;
864 static const char *coord_tween_tostring(between_enum n)
866 switch (n) {
867 case BEFORE_UNIT:
868 return "before unit";
869 case BEFORE_ITEM:
870 return "before item";
871 case AT_UNIT:
872 return "at unit";
873 case AFTER_UNIT:
874 return "after unit";
875 case AFTER_ITEM:
876 return "after item";
877 case EMPTY_NODE:
878 return "empty node";
879 case INVALID_COORD:
880 return "invalid";
881 default:
883 static char buf[30];
885 sprintf(buf, "unknown: %i", n);
886 return buf;
891 void print_coord(const char *mes, const coord_t * coord, int node)
893 if (coord == NULL) {
894 printk("%s: null\n", mes);
895 return;
897 printk("%s: item_pos = %d, unit_pos %d, tween=%s, iplug=%d\n",
898 mes, coord->item_pos, coord->unit_pos,
899 coord_tween_tostring(coord->between), coord->iplugid);
903 item_utmost_child_real_block(const coord_t * coord, sideof side,
904 reiser4_block_nr * blk)
906 return item_plugin_by_coord(coord)->f.utmost_child_real_block(coord,
907 side,
908 blk);
911 int item_utmost_child(const coord_t * coord, sideof side, jnode ** child)
913 return item_plugin_by_coord(coord)->f.utmost_child(coord, side, child);
916 /* @count bytes of flow @f got written, update correspondingly f->length,
917 f->data and f->key */
918 void move_flow_forward(flow_t * f, unsigned count)
920 if (f->data)
921 f->data += count;
922 f->length -= count;
923 set_key_offset(&f->key, get_key_offset(&f->key) + count);
927 Local variables:
928 c-indentation-style: "K&R"
929 mode-name: "LC"
930 c-basic-offset: 8
931 tab-width: 8
932 fill-column: 120
933 scroll-step: 1
934 End: