2021-10-11 19:38:01 -03:00

290 lines
6.0 KiB
C
Executable File

#ident "@(#)assign.c 1.6 93/06/08 SMI" /* From AT&T Toolchest */
/*
* ASSIGN.C
*
* Programmer: D. G. Korn
*
* Owner: D. A. Lambeth
*
* Date: April 17, 1980
*
*
* NAM_PUTVAL (NP, STRING)
*
* Assign STRING to NP.
*
* NAM_FPUTVAL (NP, STRING)
*
* Assign STRING to NP even if readonly.
*
*
* See Also: nam_longput(III), nam_free(III), nam_strval(III)
*/
#include "sh_config.h"
#include "name.h"
#ifdef MULTIBYTE
# include "national.h"
#endif /* MULTIBYTE */
extern char *strcpy();
extern char *strchr();
extern void utol(),ltou();
extern void free();
extern void nam_rjust();
extern void sh_fail();
#ifdef MULTIBYTE
static unsigned char *savep;
static unsigned char savechars[ESS_MAXCHAR+1];
static int ja_size();
#else
#define size np->value.namsz
#endif /* MULTIBYTE */
/*
* NAM_PUTVAL (NP, STRING)
*
* struct namnod *NP;
*
* char *STRING;
*
* Assign the string given by STRING to the namnod given by
* NP. STRING is converted according to the namflg field
* of NP before assignment.
*
* If NP is an array, then the element given by the
* current index is assigned to.
*
* Any freeable space associated with the old value of NP
* is released.
*
* If the copy on write,N_CWRITE flag is set then the assignment
* is made on a copy of the np created on the last shell tree.
*
*/
static char forced = 0;
void nam_fputval(np,string)
struct namnod *np;
char *string;
{
forced++;
nam_putval(np,string);
forced = 0;
#ifdef apollo
if(nam_istype(np,N_EXPORT))
{
short namlen, vallen;
char *vp = nam_strval(np);
namlen =strlen(np->namid);
vallen = strlen(vp);
ev_$set_var(np->namid,&namlen,vp,&vallen);
}
#endif /* apollo */
}
void nam_putval(np,string)
register struct namnod *np;
char *string;
{
register char *sp=string;
register union Namval *up;
register char *cp;
#ifdef MULTIBYTE
register int size = 0;
#endif /* MULTIBYTE */
register int dot;
#ifdef apollo
/* reserve space for UNIX to host file name translation */
char pathname[256];
short pathlen;
#endif /* apollo */
#ifdef NAME_SCOPE
if (nam_istype (np,N_CWRITE))
np = nam_copy(np,1);
#endif /* NAME_SCOPE */
if (forced==0 && nam_istype (np, N_RDONLY|N_RESTRICT))
{
if(nam_istype (np, N_RDONLY))
sh_fail(np->namid,e_readonly);
else
sh_fail(np->namid,e_restricted);
/* NOTREACHED */
}
if(nam_istype (np, N_ARRAY))
up = &(array_find(np,A_ASSIGN)->namval);
else
up= &np->value.namval;
if (nam_istype (np, N_INDIRECT))
up = up->up;
nam_offtype(np,~N_IMPORT);
if (nam_istype (np, N_INTGER))
{
long l;
#ifdef FLOAT
extern double sh_arith();
if (nam_istype(np, N_DOUBLE))
{
if(up->dp==0)
up->dp = new_of(double,0);
*(up->dp) = sh_arith(sp);
return;
}
#else
extern long sh_arith();
#endif /* FLOAT */
if (nam_istype (np, N_CPOINTER))
{
up->cp = sp;
return;
}
l = (sp? (long)sh_arith(sp) : (sh_lastbase=10,0));
if(np->value.namsz == 0)
np->value.namsz = sh_lastbase;
if (nam_istype (np, N_BLTNOD))
{
(*up->fp->f_ap)(l);
return;
}
if(up->lp==0)
up->lp = new_of(long,0);
*(up->lp) = l;
if(l && *sp++ == '0')
np->value.namflg |= N_UNSIGN;
return;
}
#ifdef apollo
if (nam_istype (np, N_HOST) && sp)
{
/* this routine returns the host file name given the UNIX name */
/* other non-unix hosts that use file name mapping should change this */
unix_fio_$get_name(sp,pathname,&pathlen);
pathname[pathlen] = 0;
sp = pathname;
}
#endif /* apollo */
if ((nam_istype (np, N_RJUST|N_ZFILL|N_LJUST)) && sp)
{
for(;*sp == ' '|| *sp=='\t';sp++);
if ((nam_istype (np, N_ZFILL)) && (nam_istype (np, N_LJUST)))
for(;*sp=='0';sp++);
#ifdef MULTIBYTE
if(size = np->value.namsz)
size = ja_size((unsigned char*)sp,size,nam_istype(np,N_RJUST|N_ZFILL));
#endif /* MULTIBYTE */
}
if ((!nam_istype (np, N_FREE|N_ALLOC)) && (up->cp != NULL))
free(up->cp);
if (nam_istype (np, N_ALLOC))
cp = up->cp;
else
{
np->value.namflg &= ~N_FREE;
if (sp)
{
dot = strlen(sp);
if(size==0 && nam_istype(np,N_LJUST|N_RJUST|N_ZFILL))
np->value.namsz = size = dot;
else if(size > dot)
dot = size;
cp = malloc(((unsigned)dot+1));
}
else
cp = NULL;
up->cp = cp;
}
if (!sp)
return;
if (nam_istype (np, N_LTOU))
ltou(sp,cp);
else if (nam_istype (np, N_UTOL))
utol(sp,cp);
else
strcpy (cp, sp);
if (nam_istype (np, N_RJUST) && nam_istype (np, N_ZFILL))
nam_rjust(cp,size,'0');
else if (nam_istype (np, N_RJUST))
nam_rjust(cp,size,' ');
else if (nam_istype (np, N_LJUST))
{
sp = strlen (cp) + cp;
*(cp = (cp + size)) = 0;
for (; sp < cp; *sp++ = ' ');
}
#ifdef MULTIBYTE
/* restore original string */
if(savep)
ja_restore();
#endif /* MULTIBYTE */
return;
}
#ifdef MULTIBYTE
/*
* handle left and right justified fields for multi-byte chars
* given physical size, return a logical size which reflects the
* screen width of multi-byte characters
* Multi-width characters replaced by spaces if they cross the boundary
* <type> is non-zero for right justified fields
*/
static int ja_size(str,size,type)
unsigned char *str;
int size;
{
register unsigned char *cp = str;
register int c;
register int n = size;
int oldn;
while(c = *cp++)
{
oldn = n;
/* find character set number */
c = echarset(c);
/* allow room for excess input bytes */
if(c)
{
n += (in_csize(c)-out_csize(c)+(c>=2));
cp += (in_csize(c)-(c==1));
}
size -= out_csize(c);
if(size<=0 && type==0)
break;
}
/* check for right justified fields that need truncating */
if(size <0)
{
if(type==0)
{
/* left justified and character crosses field boundary */
n = oldn;
/* save boundary char and replace with spaces */
size = in_csize(c)+(c>2);
savechars[size] = 0;
while(size--)
{
savechars[size] = *--cp;
*cp = ' ';
}
savep = cp;
}
size = -size;
if(type)
n -= (ja_size(str,size,0)-size);
}
return(n);
}
int ja_restore()
{
register unsigned char *cp = savechars;
while(*cp)
*savep++ = *cp++;
savep = 0;
}
#endif /* MULTIBYTE */