henesyinit from p9f47575dc5 years agoHistory
311 lines · 7.7 KB · C
RawDownload
#include <u.h>#include <libc.h>#include "system.h"# include "stdio.h"# include "defines.h"# include "object.h"# include "dict.h"#include "path.h"#ifndef Plan9#include "njerq.h"#endif#include "graphics.h" voidlengthOP(void){	int		length ;	struct	object	object ; 	object = pop() ;	switch(object.type){	case OB_ARRAY :		length = object.value.v_array.length ;		break ; 	case OB_DICTIONARY :		length = object.value.v_dict->cur ;		break ;	case OB_NAME:	case OB_STRING :		length = object.value.v_string.length ;		break ; 	default :		fprintf(stderr,"type %o\n",object.type);		pserror("typecheck", "length") ;	}	push(makeint(length)) ;} voidarrayOP(void){	int		i, length ;	struct	object	array, null, object ; 	object = integer("array");	/*to avoid compiler bug*/	length = object.value.v_int ;	array = makearray(length,XA_LITERAL) ;	null = makenull() ;	for ( i=0 ; i<length ; i++ )		array.value.v_array.object[i] = null ;	push(array) ;} voidendarrayOP(void){	int		i ;	struct	object	object , mark; 	counttomarkOP() ;	arrayOP() ;	object = pop() ;	for ( i=object.value.v_array.length-1 ; i>=0 ; i-- )		object.value.v_array.object[i] = pop() ;	mark=pop();	if ( mark.type != OB_MARK )		error("expecting mark in endarray") ;	push(object) ;} voidputOP(void){	struct	object	source, index, dest ; 	source = pop() ;	index = pop() ;	dest = pop() ;	switch(dest.type){	case OB_ARRAY :		if ( index.type != OB_INT )			pserror("typecheck", "put array") ;		if ( index.value.v_int < 0  ||			index.value.v_int >= dest.value.v_array.length ){			fprintf(stderr,"val %d dest leng %d\n",index.value.v_int,			   dest.value.v_array.length);			pserror("rangecheck", "put array") ;		}		SAVEITEM(dest.value.v_array.object[index.value.v_int]) ;		dest.value.v_array.object[index.value.v_int] = source ;		return; 	case OB_STRING :		if ( source.type != OB_INT )			pserror("typecheck", "put string") ;		if ( source.value.v_int < 0  ||  source.value.v_int > 255 ){			fprintf(stderr,"source %d\n",source.value.v_int);			pserror("rangecheck", "put string") ;		}		if ( index.type != OB_INT )			pserror("typecheck", "put string - index type") ;		if ( index.value.v_int < 0  ||			index.value.v_int >= dest.value.v_string.length ){			fprintf(stderr,"val %d dest leng %d too small\n",index.value.v_int,			   dest.value.v_array.length);			pserror("rangecheck", "put string") ;		}		SAVEITEM(dest.value.v_string.chars[index.value.v_int]) ;		dest.value.v_string.chars[index.value.v_int] = source.value.v_int ;		return; 	case OB_DICTIONARY :		if(decryptf||Graphics.incharpath)dictput(dest.value.v_dict,index,source) ;		else odictput(dest.value.v_dict,index,source) ;		return; 	default :		pserror("typecheck", "put") ;	}} voidgetOP(void){	struct	object	target, locator, object ;	int index; 	locator = pop() ;	target = pop() ;	switch(target.type){	case OB_ARRAY :		if ( locator.type != OB_INT )			pserror("typecheck", "get array") ;		index = locator.value.v_int ;		if ( index < 0  ||  index >= target.value.v_array.length ){			fprintf(stderr,"bad index %d leng %d\n",index,				target.value.v_array.length);			pserror("rangecheck", "get array") ;		}		push(target.value.v_array.object[index]) ;		return; 	case OB_STRING :		if ( locator.type != OB_INT )			pserror("typecheck", "get string") ;		index = locator.value.v_int ;		if ( index < 0  ||  index >= target.value.v_string.length ){			fprintf(stderr,"bad index %d leng %d\n",index,				target.value.v_string.length);			pserror("rangecheck", "get string") ;		}		push(makeint((int)target.value.v_string.chars[index])) ;		return; 	case OB_DICTIONARY :		if(decryptf||Graphics.incharpath)			object = dictget(target.value.v_dict,locator) ;		else object = odictget(target.value.v_dict,locator) ;		if ( object.type == OB_NONE ){			if(locator.type == OB_INT)				fprintf(stderr,"dict loctype %d val %d\n",locator.type,					locator.value.v_int);			else fprintf(stderr,"dict loctype %d val %s\n",locator.type,				locator.value.v_string.chars);			pserror("undefined", "get dict") ;		}		push(object) ;		return; 	default :		pserror("typecheck", "get") ;	}} voidgetintervalOP(void){	int		i, count, index ;	struct	object	object, subarray ; 	object=integer("getinterval");	count = object.value.v_int ;	object=integer("getinterval");	index = object.value.v_int ;	object = pop() ;	switch(object.type){	case OB_ARRAY :		if ( index < 0  ||  index >= object.value.v_array.length ){			fprintf(stderr,"bad index %d leng %d\n",				index, object.value.v_array.length);			pserror("rangecheck", "getinterval array");		}		if(count < 0 || index+count > object.value.v_array.length){			fprintf(stderr,"bad count %d leng %d\n",				count, object.value.v_array.length);			pserror("rangecheck", "getinterval array") ;		}		subarray = object ;		subarray.value.v_array.object += index ;		subarray.value.v_array.length = count ;		break ; 	case OB_STRING :		if ( index < 0  ||  index >= object.value.v_string.length ){			fprintf(stderr,"bad index %d leng %d\n",index,				object.value.v_array.length);			pserror("rangecheck", "getinterval string");		}		if(count< 0 || index+count > object.value.v_string.length){			fprintf(stderr,"bad count %d index %d leng %d\n",				count, index,object.value.v_string.length);			pserror("rangecheck", "getinterval string");		}		subarray = object;		subarray.value.v_string.chars += index ;		subarray.value.v_string.length = count ;		break ; 	default :		pserror("typecheck", "getinterval") ;	}	push(subarray) ;} voidputintervalOP(void){	int		index, i ;	struct	object	source, dest, object ; 	source = pop() ;	object = integer("putinterval");	index = object.value.v_int ;	dest = pop() ;	if ( source.type != dest.type )		pserror("typecheck", "putinterval types different") ; 	switch(dest.type){	case OB_ARRAY :		if(source.value.v_array.length <= 0)break;		if ( index < 0  ||  index >= dest.value.v_array.length ){			fprintf(stderr,"bad index %d arr_leng %d\n",index,				dest.value.v_array.length);			pserror("rangecheck", "putinterval array");		}		if ( index+source.value.v_array.length > dest.value.v_array.length){			fprintf(stderr,"dest too small %d %d\n",				index+source.value.v_array.length,				dest.value.v_array.length);			pserror("rangecheck", "putinterval array");		}		for ( i=0 ; i<source.value.v_array.length ; i++ ){			SAVEITEM(dest.value.v_array.object[index+i]) ;			dest.value.v_array.object[index+i] = source.value.v_array.object[i] ;		}		return; 	case OB_STRING :		if ( index < 0  ||  index >= dest.value.v_string.length ){			fprintf(stderr,"bad index %d st_leng %d\n", index,				dest.value.v_string.length);			pserror("rangecheck", "putinterval string") ;		}		if ( index+source.value.v_string.length > dest.value.v_string.length ){			fprintf(stderr,"dest too small %d %d\n",				index+source.value.v_string.length,				dest.value.v_string.length);			pserror("rangecheck", "putinterval string") ;		}		for ( i=0 ; i<source.value.v_string.length ; i++ ){			SAVEITEM(dest.value.v_string.chars[index+i]) ;			dest.value.v_string.chars[index+i] = source.value.v_string.chars[i] ;		}		return; 	default :		pserror("typecheck", "putinterval") ;	}} voidaloadOP(void){	int		i ;	struct	object	array ; 	array = pop() ;	if ( array.type != OB_ARRAY )		pserror("typecheck", "aload not array") ;	for ( i=0 ; i<array.value.v_array.length ; i++ )		push(array.value.v_array.object[i]) ;	push(array) ;} voidastoreOP(void){	int		i ;	struct	object	array ; 	array = pop() ;	if ( array.type != OB_ARRAY )		pserror("typecheck", "astore not array") ;	for ( i=0 ; i<array.value.v_array.length ; i++ ){		SAVEITEM(array.value.v_array.object[array.value.v_array.length-i-1]) ;		array.value.v_array.object[array.value.v_array.length-i-1] = pop();	}	push(array) ;}