/* replace a range of lines with the joined text of those lines */ bool join_lines( const int from, const int to, const bool isglobal ) { static char * buf = 0; static int bufsz = 0; int size = 0; line_t * const ep = search_line_node( inc_addr( to ) ); line_t * bp = search_line_node( from ); while( bp != ep ) { const char * const s = get_sbuf_line( bp ); if( !s || !resize_buffer( &buf, &bufsz, size + bp->len ) ) return false; memcpy( buf + size, s, bp->len ); size += bp->len; bp = bp->q_forw; } if( !resize_buffer( &buf, &bufsz, size + 2 ) ) return false; memcpy( buf + size, "\n", 2 ); size += 2; if( !delete_lines( from, to, isglobal ) ) return false; current_addr_ = from - 1; disable_interrupts(); if( !put_sbuf_line( buf, size, current_addr_ ) || !push_undo_atom( UADD, current_addr_, current_addr_ ) ) { enable_interrupts(); return false; } modified_ = true; enable_interrupts(); return true; }
/* move a range of lines */ bool move_lines( const int first_addr, const int second_addr, const int addr, const bool isglobal ) { line_t *b1, *a1, *b2, *a2; int n = inc_addr( second_addr ); int p = first_addr - 1; disable_interrupts(); if( addr == first_addr - 1 || addr == second_addr ) { a2 = search_line_node( n ); b2 = search_line_node( p ); current_addr_ = second_addr; } else if( !push_undo_atom( UMOV, p, n ) || !push_undo_atom( UMOV, addr, inc_addr( addr ) ) ) { enable_interrupts(); return false; } else { a1 = search_line_node( n ); if( addr < first_addr ) { b1 = search_line_node( p ); b2 = search_line_node( addr ); /* this search_line_node last! */ } else { b2 = search_line_node( addr ); b1 = search_line_node( p ); /* this search_line_node last! */ } a2 = b2->q_forw; link_nodes( b2, b1->q_forw ); link_nodes( a1->q_back, a2 ); link_nodes( b1, a1 ); current_addr_ = addr + ( ( addr < first_addr ) ? second_addr - first_addr + 1 : 0 ); } if( isglobal ) unset_active_nodes( b2->q_forw, a2 ); modified_ = true; enable_interrupts(); return true; }
/* Read a variable number of 32-bit values. Parameter count is not allowed to * exceed USB_MAX_IOREAD32_COUNT. */ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr, unsigned int count) { int r; int i; zd_addr_t *a16; u16 *v16; unsigned int count16; if (count > USB_MAX_IOREAD32_COUNT) return -EINVAL; /* Allocate a single memory block for values and addresses. */ count16 = 2*count; a16 = (zd_addr_t *) kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)), GFP_KERNEL); if (!a16) { dev_dbg_f(zd_chip_dev(chip), "error ENOMEM in allocation of a16\n"); r = -ENOMEM; goto out; } v16 = (u16 *)(a16 + count16); for (i = 0; i < count; i++) { int j = 2*i; /* We read the high word always first. */ a16[j] = inc_addr(addr[i]); a16[j+1] = addr[i]; } r = zd_ioread16v_locked(chip, v16, a16, count16); if (r) { dev_dbg_f(zd_chip_dev(chip), "error: zd_ioread16v_locked. Error number %d\n", r); goto out; } for (i = 0; i < count; i++) { int j = 2*i; values[i] = (v16[j] << 16) | v16[j+1]; } out: kfree((void *)a16); return r; }
/* delete a range of lines */ bool delete_lines( const int from, const int to, const bool isglobal ) { line_t *n, *p; if( !yank_lines( from, to ) ) return false; disable_interrupts(); if( !push_undo_atom( UDEL, from, to ) ) { enable_interrupts(); return false; } n = search_line_node( inc_addr( to ) ); p = search_line_node( from - 1 ); /* this search_line_node last! */ if( isglobal ) unset_active_nodes( p->q_forw, n ); link_nodes( p, n ); last_addr_ -= to - from + 1; current_addr_ = from - 1; modified_ = true; enable_interrupts(); return true; }
int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, unsigned int count) { int i, j, r; struct zd_ioreq16 *ioreqs16; unsigned int count16; ZD_ASSERT(mutex_is_locked(&chip->mutex)); if (count == 0) return 0; if (count > USB_MAX_IOWRITE32_COUNT) return -EINVAL; /* Allocate a single memory block for values and addresses. */ count16 = 2*count; ioreqs16 = kmalloc(count16 * sizeof(struct zd_ioreq16), GFP_KERNEL); if (!ioreqs16) { r = -ENOMEM; dev_dbg_f(zd_chip_dev(chip), "error %d in ioreqs16 allocation\n", r); goto out; } for (i = 0; i < count; i++) { j = 2*i; /* We write the high word always first. */ ioreqs16[j].value = ioreqs[i].value >> 16; ioreqs16[j].addr = inc_addr(ioreqs[i].addr); ioreqs16[j+1].value = ioreqs[i].value; ioreqs16[j+1].addr = ioreqs[i].addr; } r = zd_usb_iowrite16v(&chip->usb, ioreqs16, count16); #ifdef DEBUG if (r) { dev_dbg_f(zd_chip_dev(chip), "error %d in zd_usb_write16v\n", r); } #endif /* DEBUG */ out: kfree(ioreqs16); return r; }
/* copy a range of lines to the cut buffer */ bool yank_lines( const int from, const int to ) { line_t * const ep = search_line_node( inc_addr( to ) ); line_t * bp = search_line_node( from ); line_t * lp = &yank_buffer_head; line_t * p; clear_yank_buffer(); while( bp != ep ) { disable_interrupts(); p = dup_line_node( bp ); if( !p ) { enable_interrupts(); return false; } insert_node( p, lp ); bp = bp->q_forw; lp = p; enable_interrupts(); } return true; }
/* return the address of the next line matching a pattern in a given direction. wrap around begin/end of editor buffer if necessary */ int get_matching_node_addr( const char **ibufpp, const char forward ) { regex_t *pat = get_compiled_pattern( ibufpp ); int addr = current_addr(); if( !pat ) return -1; do { addr = ( forward ? inc_addr( addr ) : dec_addr( addr ) ); if( addr ) { line_t *lp = search_line_node( addr ); char *s = get_sbuf_line( lp ); if( !s ) return -1; if( isbinary() ) nul_to_newline( s, lp->len ); if( !regexec( pat, s, 0, 0, 0 ) ) return addr; } } while( addr != current_addr() ); set_error_msg( "No match" ); return -1; }
static int _zd_iowrite32v_async_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, unsigned int count) { int i, j, r; struct zd_ioreq16 ioreqs16[USB_MAX_IOWRITE32_COUNT * 2]; unsigned int count16; /* Use stack for values and addresses. */ ZD_ASSERT(mutex_is_locked(&chip->mutex)); if (count == 0) return 0; if (count > USB_MAX_IOWRITE32_COUNT) return -EINVAL; count16 = 2 * count; BUG_ON(count16 * sizeof(struct zd_ioreq16) > sizeof(ioreqs16)); for (i = 0; i < count; i++) { j = 2*i; /* We write the high word always first. */ ioreqs16[j].value = ioreqs[i].value >> 16; ioreqs16[j].addr = inc_addr(ioreqs[i].addr); ioreqs16[j+1].value = ioreqs[i].value; ioreqs16[j+1].addr = ioreqs[i].addr; } r = zd_usb_iowrite16v_async(&chip->usb, ioreqs16, count16); #ifdef DEBUG if (r) { dev_dbg_f(zd_chip_dev(chip), "error %d in zd_usb_write16v\n", r); } #endif /* DEBUG */ return r; }
/* Read a variable number of 32-bit values. Parameter count is not allowed to * exceed USB_MAX_IOREAD32_COUNT. */ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr, unsigned int count) { int r; int i; zd_addr_t a16[USB_MAX_IOREAD32_COUNT * 2]; u16 v16[USB_MAX_IOREAD32_COUNT * 2]; unsigned int count16; if (count > USB_MAX_IOREAD32_COUNT) return -EINVAL; /* Use stack for values and addresses. */ count16 = 2 * count; BUG_ON(count16 * sizeof(zd_addr_t) > sizeof(a16)); BUG_ON(count16 * sizeof(u16) > sizeof(v16)); for (i = 0; i < count; i++) { int j = 2*i; /* We read the high word always first. */ a16[j] = inc_addr(addr[i]); a16[j+1] = addr[i]; } r = zd_ioread16v_locked(chip, v16, a16, count16); if (r) { dev_dbg_f(zd_chip_dev(chip), "error: %s. Error number %d\n", __func__, r); return r; } for (i = 0; i < count; i++) { int j = 2*i; values[i] = (v16[j] << 16) | v16[j+1]; } return 0; }