📄 blkcpy.c
字号:
/* * blkcpy - general values and related routines used by the calculator * * Copyright (C) 1999-2006 Landon Curt Noll and Ernest Bowen * * Primary author: Landon Curt Noll * * Calc is open software; you can redistribute it and/or modify it under * the terms of the version 2.1 of the GNU Lesser General Public License * as published by the Free Software Foundation. * * Calc is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General * Public License for more details. * * A copy of version 2.1 of the GNU Lesser General Public License is * distributed with calc under the filename COPYING-LGPL. You should have * received a copy with calc; if not, write to Free Software Foundation, Inc. * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * * @(#) $Revision: 29.9 $ * @(#) $Id: blkcpy.c,v 29.9 2006/05/20 08:43:55 chongo Exp $ * @(#) $Source: /usr/local/src/cmd/calc/RCS/blkcpy.c,v $ * * Under source code control: 1997/04/18 20:41:26 * File existed as early as: 1997 * * Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/ */#include <stdio.h>#include <sys/types.h>#include "calc.h"#include "value.h"#include "file.h"#include "blkcpy.h"#include "string.h"/* * copystod - copy num indexed items from source value to destination value * * given: * ssi = source starting index * num = number of items (octets or values) to be copied * sdi = destination starting index * * returns: * zero if successful, otherwise error-code number */intcopystod(VALUE *svp, long ssi, long num, VALUE *dvp, long dsi){ BLOCK *sblk; BLOCK *dblk; BOOL noreloc; sblk = NULL; dblk = NULL; /* * check protections */ if (svp->v_subtype & V_NOCOPYFROM) return E_COPY13; if (dvp->v_subtype & V_NOCOPYTO) return E_COPY14; noreloc = ((dvp->v_subtype & V_NOREALLOC) != 0); /* * determine/check source type */ switch(svp->v_type) { case V_NBLOCK: if (svp->v_nblock->subtype & V_NOCOPYFROM) return E_COPY15; sblk = svp->v_nblock->blk; if (sblk->data == NULL) return E_COPY8; break; case V_BLOCK: sblk = svp->v_block; break; case V_STR: case V_OCTET: case V_NUM: case V_FILE: case V_MAT: case V_LIST: break; default: return E_COPY9; } /* * determine/check destination type */ switch(dvp->v_type) { case V_NBLOCK: if (dvp->v_nblock->subtype & V_NOCOPYTO) return E_COPY16; noreloc |=((dvp->v_nblock->subtype & V_NOREALLOC) != 0); dblk = dvp->v_nblock->blk; if (dblk->data == NULL) return E_COPY10; break; case V_BLOCK: noreloc = ((dvp->v_subtype & V_NOREALLOC) != 0); dblk = dvp->v_block; break; case V_STR: case V_NUM: case V_FILE: case V_MAT: case V_LIST: break; default: return E_COPY11; } /* * copy based on source */ switch (svp->v_type) { case V_BLOCK: case V_NBLOCK: /* * copy from a block */ switch(dvp->v_type) { case V_BLOCK: case V_NBLOCK: return copyblk2blk(sblk, ssi, num, dblk, dsi, noreloc); case V_NUM: { NUMBER *n; /* modified number */ int rt; /* return code */ /* copy to a number */ rt = copyblk2num(sblk, ssi, num, dvp->v_num, dsi, &n); if (rt == 0) { qfree(dvp->v_num); dvp->v_num = n; } return rt; } case V_FILE: return copyblk2file(sblk, ssi, num, dvp->v_file, dsi); case V_MAT: return copyblk2mat(sblk, ssi, num, dvp->v_mat, dsi); case V_STR: return copyblk2str(sblk, ssi, num, dvp->v_str, dsi); } return E_COPY12; case V_STR: switch(dvp->v_type) { case V_BLOCK: case V_NBLOCK: /* copy to a block */ return copystr2blk(svp->v_str, ssi, num, dblk, dsi, noreloc); case V_FILE: return copystr2file(svp->v_str, ssi, num, dvp->v_file, dsi); case V_STR: return copystr2str(svp->v_str, ssi, num, dvp->v_str, dsi); } return E_COPY12; case V_OCTET: switch(dvp->v_type) { case V_BLOCK: case V_NBLOCK: return copyostr2blk((char *) svp->v_octet, ssi, num, dblk, dsi, noreloc); case V_STR: return copyostr2str((char *) svp->v_octet, ssi, num, dvp->v_str, dsi); } return E_COPY12; case V_NUM: /* * copy from a number */ if (dblk != NULL) { /* copy to a block */ return copynum2blk(svp->v_num, ssi, num, dblk, dsi, noreloc); } switch (dvp->v_type) { case V_MAT: /* copy to a matrix */ return E_COPY12; /* not yet - XXX */ case V_LIST: /* copy to a list */ return E_COPY12; /* not yet - XXX */ } break; case V_FILE: /* * copy from a file */ if (dblk != NULL) { /* copy to a block */ return copyfile2blk(svp->v_file, ssi, num, dblk, dsi, noreloc); } switch (dvp->v_type) { case V_NUM: /* copy to a number */ return E_COPY12; /* not yet - XXX */ } break; case V_MAT: /* * copy from a matrix */ if (dblk != NULL) { /* copy to a block */ return copymat2blk(svp->v_mat, ssi, num, dblk, dsi, noreloc); } switch (dvp->v_type) { case V_MAT: /* copy to a matrix */ return copymat2mat(svp->v_mat, ssi, num, dvp->v_mat, dsi); case V_LIST: /* copy to a list */ return copymat2list(svp->v_mat, ssi, num, dvp->v_list, dsi); } break; case V_LIST: /* * copy from a list */ if (dblk != NULL) { /* copy to a block */ return E_COPY12; /* not yet - XXX */ } switch (dvp->v_type) { case V_MAT: /* copy to a matrix */ return copylist2mat(svp->v_list, ssi, num, dvp->v_mat, dsi); case V_LIST: /* copy to a list */ return copylist2list(svp->v_list, ssi, num, dvp->v_list, dsi); } break; } /* * unsupported copy combination */ return E_COPY12;}/* * copymat2mat - copy matrix to matrix */intcopymat2mat(MATRIX *smat, long ssi, long num, MATRIX *dmat, long dsi){ long i; VALUE *vp; VALUE *vq; VALUE *vtemp; unsigned short subtype; if (ssi > smat->m_size) return E_COPY2; if (num < 0) num = smat->m_size - ssi; if (ssi + num > smat->m_size) return E_COPY5; if (num == 0) return 0; if (dsi < 0) dsi = 0; if (dsi + num > dmat->m_size) return E_COPY7; vtemp = (VALUE *) malloc(num * sizeof(VALUE)); if (vtemp == NULL) { math_error("Out of memory for mat-to-mat copy"); /*NOTREACHED*/ } vp = smat->m_table + ssi; vq = vtemp; i = num; while (i-- > 0) copyvalue(vp++, vq++); vp = vtemp; vq = dmat->m_table + dsi; for (i = num; i > 0; i--, vp++, vq++) { subtype = vq->v_subtype; freevalue(vq); *vq = *vp; vq->v_subtype |= subtype; } free(vtemp); return 0;}/* * copyblk2mat - copy block to matrix */intcopyblk2mat(BLOCK *blk, long ssi, long num, MATRIX *dmat, long dsi){ OCTET *op; VALUE *vp; VALUE *vq; VALUE *vtemp; long i; unsigned short subtype; if (ssi > blk->datalen) return E_COPY2; if (num < 0) num = blk->datalen - ssi; if (ssi + num > blk->datalen) return E_COPY5; if (num == 0) return 0; if (dsi < 0) dsi = 0; if (dsi + num > dmat->m_size) return E_COPY7; op = blk->data + ssi; vtemp = (VALUE *) malloc(num * sizeof(VALUE)); if (vtemp == NULL) { math_error("Out of memory for block-to-matrix copy"); /*NOTREACHED*/ } vp = vtemp; i = num; while (i-- > 0) { vp->v_type = V_NUM; vp->v_subtype = V_NOSUBTYPE; vp->v_num = itoq((long) *op++); vp++; } vp = vtemp; vq = dmat->m_table + dsi; for (i = num; i > 0; i--, vp++, vq++) { subtype = vq->v_subtype; freevalue(vq); *vq = *vp; vq->v_subtype |= subtype; } free(vtemp); return 0;}/* * copymat2blk - copy matrix to block */intcopymat2blk(MATRIX *smat, long ssi, long num, BLOCK *dblk, long dsi, BOOL noreloc){ long i; long newlen; long newsize; USB8 *newdata; VALUE *vp; OCTET *op; if (ssi > smat->m_size) return E_COPY2; if (num < 0) num = smat->m_size - ssi; if (num == 0) return 0; if (ssi + num > smat->m_size) return E_COPY5; if (dsi < 0) dsi = dblk->datalen; newlen = dsi + num; if (newlen <= 0) return E_COPY7; if (newlen >= dblk->maxsize) { if (noreloc) return E_COPY17; newsize = (1 + newlen/dblk->blkchunk) * dblk->blkchunk; newdata = (USB8*) realloc(dblk->data, newsize); if (newdata == NULL) { math_error("Out of memory for matrix-to-block copy"); /*NOTREACHED*/ } dblk->data = newdata; dblk->maxsize = newsize; } vp = smat->m_table + ssi; op = dblk->data + dsi; for (i = num; i > 0; i--) copy2octet(vp++, op++); if (newlen > dblk->datalen) dblk->datalen = newlen; return 0;}/* * copymat2list - copy matrix to list */intcopymat2list(MATRIX *smat, long ssi, long num, LIST *lp, long dsi){ VALUE *vp; VALUE *vq; LISTELEM *ep; VALUE *vtemp; long i; unsigned short subtype; if (ssi > smat->m_size) return E_COPY2; if (num < 0) num = smat->m_size - ssi; if (num == 0) return 0; if (ssi + num > smat->m_size) return E_COPY5; if (dsi < 0) dsi = 0; if (dsi + num > lp->l_count) return E_COPY7; vtemp = (VALUE *) malloc(num * sizeof(VALUE)); if (vtemp == NULL) { math_error("Out of memory for matrix-to-list copy"); /*NOTREACHED*/ } vp = smat->m_table + ssi; vq = vtemp; i = num; while (i-- > 0) copyvalue(vp++, vq++); vq = vtemp; ep = listelement(lp, (long) dsi); i = num; while (i-- > 0) { subtype = ep->e_value.v_subtype; freevalue(&ep->e_value); ep->e_value = *vq++; ep->e_value.v_subtype |= subtype; ep = ep->e_next; } free(vtemp); return 0;}/* * copymat2list - copy list to matrix */intcopylist2mat(LIST *lp, long ssi, long num, MATRIX *dmat, long dsi){ VALUE *vp; VALUE *vq; LISTELEM *ep; VALUE *vtemp; long i; unsigned short subtype; if (ssi > lp->l_count) return E_COPY2; if (num < 0) num = lp->l_count - ssi; if (num == 0) return 0; if (ssi + num > lp->l_count) return E_COPY5; if (dsi < 0) dsi = 0; if (dsi + num > dmat->m_size) return E_COPY7; vtemp = (VALUE *) malloc(num * sizeof(VALUE)); if (vtemp == NULL) { math_error("Out of memory for list-to-matrix copy"); /*NOTREACHED*/ } ep = listelement(lp, (long) ssi); vp = vtemp; i = num; while (i-- > 0) { copyvalue(&ep->e_value, vp++); ep = ep->e_next; } vp = vtemp; vq = dmat->m_table + dsi; for (i = num; i > 0; i--, vp++, vq++) { subtype = vq->v_subtype; freevalue(vq); *vq = *vp; vq->v_subtype |= subtype; } free(vtemp); return 0;}/* * copylist2list - copy list to list */intcopylist2list(LIST *slp, long ssi, long num, LIST *dlp, long dsi){ long i; LISTELEM *sep; LISTELEM *dep; VALUE *vtemp; VALUE *vp; unsigned short subtype; if (ssi > slp->l_count) return E_COPY2; if (num < 0) num = slp->l_count - ssi; if (num == 0) return 0; if (ssi + num > slp->l_count) return E_COPY5; if (dsi < 0) dsi = 0; if (dsi + num > dlp->l_count) return E_COPY7; vtemp = (VALUE *) malloc(num * sizeof(VALUE)); if (vtemp == NULL) { math_error("Out of memory for list-to-list copy"); /*NOTREACHED*/ } sep = listelement(slp, (long) ssi); vp = vtemp; i = num; while (i-- > 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -