blob: a044f647dba04660e9cc056b919db686b8fdb445 [file] [log] [blame]
/*
* Copyright (c) 2005, 2008 Sun Microsystems, Inc. All Rights Reserved.
* Use is subject to license terms.
*
* Copyright (c) 1984 AT&T
* All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "apr.h"
#include "apr_strings.h"
#include "libsed.h"
#include "sed.h"
#include "regexp.h"
#define CCEOF 22
static int fcomp(sed_commands_t *commands, apr_file_t *fin);
static char *compsub(sed_commands_t *commands,
sed_comp_args *compargs, char *rhsbuf);
static int rline(sed_commands_t *commands, apr_file_t *fin,
char *lbuf, char *lbend);
static char *address(sed_commands_t *commands, char *expbuf,
apr_status_t* status);
static char *text(sed_commands_t *commands, char *textbuf, char *endbuf);
static sed_label_t *search(sed_commands_t *commands);
static char *ycomp(sed_commands_t *commands, char *expbuf);
static char *comple(sed_commands_t *commands, sed_comp_args *compargs,
char *x1, char *ep, char *x3, char x4);
static sed_reptr_t *alloc_reptr(sed_commands_t *commands);
static int check_finalized(const sed_commands_t *commands);
void command_errf(sed_commands_t *commands, const char *fmt, ...)
{
if (commands->errfn && commands->pool) {
va_list args;
const char* error;
va_start(args, fmt);
error = apr_pvsprintf(commands->pool, fmt, args);
commands->errfn(commands->data, error);
va_end(args);
}
}
/*
* sed_init_commands
*/
apr_status_t sed_init_commands(sed_commands_t *commands, sed_err_fn_t *errfn, void *data,
apr_pool_t *p)
{
memset(commands, 0, sizeof(*commands));
commands->errfn = errfn;
commands->data = data;
commands->labtab = commands->ltab;
commands->lab = commands->labtab + 1;
commands->pool = p;
commands->respace = apr_pcalloc(p, RESIZE);
if (commands->respace == NULL) {
command_errf(commands, SEDERR_OOMMES);
return APR_EGENERAL;
}
commands->rep = alloc_reptr(commands);
if (commands->rep == NULL)
return APR_EGENERAL;
commands->rep->ad1 = commands->respace;
commands->reend = &commands->respace[RESIZE - 1];
commands->labend = &commands->labtab[SED_LABSIZE];
commands->canbefinal = 1;
return APR_SUCCESS;
}
/*
* sed_destroy_commands
*/
void sed_destroy_commands(sed_commands_t *commands)
{
}
/*
* sed_compile_string
*/
apr_status_t sed_compile_string(sed_commands_t *commands, const char *s)
{
apr_status_t rv;
commands->earg = s;
commands->eflag = 1;
rv = fcomp(commands, NULL);
if (rv == APR_SUCCESS)
commands->canbefinal = check_finalized(commands);
commands->eflag = 0;
return (rv != 0 ? APR_EGENERAL : APR_SUCCESS);
}
/*
* sed_compile_file
*/
apr_status_t sed_compile_file(sed_commands_t *commands, apr_file_t *fin)
{
apr_status_t rv = fcomp(commands, fin);
return (rv != 0 ? APR_EGENERAL : APR_SUCCESS);
}
/*
* sed_get_finalize_error
*/
char* sed_get_finalize_error(const sed_commands_t *commands, apr_pool_t* pool)
{
const sed_label_t *lab;
if (commands->depth) {
return SEDERR_TMOMES;
}
/* Empty branch chain is not a issue */
for (lab = commands->labtab + 1; lab < commands->lab; lab++) {
char *error;
if (lab->address == 0) {
error = apr_psprintf(pool, SEDERR_ULMES, lab->asc);
return error;
}
if (lab->chain) {
return SEDERR_INTERNAL;
}
}
return NULL;
}
/*
* sed_canbe_finalized
*/
int sed_canbe_finalized(const sed_commands_t *commands)
{
return commands->canbefinal;
}
/*
* check_finalized
*/
static int check_finalized(const sed_commands_t *commands)
{
const sed_label_t *lab;
if (commands->depth) {
return 0;
}
/* Empty branch chain is not a issue */
for (lab = commands->labtab + 1; lab < commands->lab; lab++) {
if (lab->address == 0 || (lab->chain)) {
return 0;
}
}
return 1;
}
/*
* dechain
*/
static void dechain(sed_label_t *lpt, sed_reptr_t *address)
{
sed_reptr_t *rep;
if ((lpt == NULL) || (lpt->chain == NULL) || (address == NULL))
return;
rep = lpt->chain;
while (rep->lb1) {
sed_reptr_t *next;
next = rep->lb1;
rep->lb1 = address;
rep = next;
}
rep->lb1 = address;
lpt->chain = NULL;
}
/*
* fcomp
*/
static int fcomp(sed_commands_t *commands, apr_file_t *fin)
{
char *p, *op, *tp;
sed_reptr_t *pt, *pt1;
int i, ii;
sed_label_t *lpt;
char fnamebuf[APR_PATH_MAX];
apr_status_t status;
sed_comp_args compargs;
op = commands->lastre;
if (!commands->linebuf) {
commands->linebuf = apr_pcalloc(commands->pool, LBSIZE + 1);
}
if (rline(commands, fin, commands->linebuf,
(commands->linebuf + LBSIZE + 1)) < 0)
return 0;
if (*commands->linebuf == '#') {
if (commands->linebuf[1] == 'n')
commands->nflag = 1;
}
else {
commands->cp = commands->linebuf;
goto comploop;
}
for (;;) {
if (rline(commands, fin, commands->linebuf,
(commands->linebuf + LBSIZE + 1)) < 0)
break;
commands->cp = commands->linebuf;
comploop:
while (*commands->cp == ' ' || *commands->cp == '\t')
commands->cp++;
if (*commands->cp == '\0' || *commands->cp == '#')
continue;
if (*commands->cp == ';') {
commands->cp++;
goto comploop;
}
p = address(commands, commands->rep->ad1, &status);
if (status != APR_SUCCESS) {
command_errf(commands, SEDERR_CGMES, commands->linebuf);
return -1;
}
if (p == commands->rep->ad1) {
if (op)
commands->rep->ad1 = op;
else {
command_errf(commands, SEDERR_NRMES);
return -1;
}
} else if (p == 0) {
p = commands->rep->ad1;
commands->rep->ad1 = 0;
} else {
op = commands->rep->ad1;
if (*commands->cp == ',' || *commands->cp == ';') {
commands->cp++;
commands->rep->ad2 = p;
p = address(commands, commands->rep->ad2, &status);
if ((status != APR_SUCCESS) || (p == 0)) {
command_errf(commands, SEDERR_CGMES, commands->linebuf);
return -1;
}
if (p == commands->rep->ad2)
commands->rep->ad2 = op;
else
op = commands->rep->ad2;
} else
commands->rep->ad2 = 0;
}
if(p > &commands->respace[RESIZE-1]) {
command_errf(commands, SEDERR_TMMES, commands->linebuf);
return -1;
}
while (*commands->cp == ' ' || *commands->cp == '\t')
commands->cp++;
swit:
switch(*commands->cp++) {
default:
command_errf(commands, SEDERR_UCMES, commands->linebuf);
return -1;
case '!':
commands->rep->negfl = 1;
goto swit;
case '{':
commands->rep->command = BCOM;
commands->rep->negfl = !(commands->rep->negfl);
commands->cmpend[commands->depth++] = &commands->rep->lb1;
commands->rep = alloc_reptr(commands);
commands->rep->ad1 = p;
if (*commands->cp == '\0')
continue;
goto comploop;
case '}':
if (commands->rep->ad1) {
command_errf(commands, SEDERR_AD0MES, commands->linebuf);
return -1;
}
if (--commands->depth < 0) {
command_errf(commands, SEDERR_TMCMES);
return -1;
}
*commands->cmpend[commands->depth] = commands->rep;
commands->rep->ad1 = p;
continue;
case '=':
commands->rep->command = EQCOM;
if (commands->rep->ad2) {
command_errf(commands, SEDERR_AD1MES, commands->linebuf);
return -1;
}
break;
case ':':
if (commands->rep->ad1) {
command_errf(commands, SEDERR_AD0MES, commands->linebuf);
return -1;
}
while (*commands->cp++ == ' ');
commands->cp--;
tp = commands->lab->asc;
while ((*tp++ = *commands->cp++)) {
if (tp >= &(commands->lab->asc[8])) {
command_errf(commands, SEDERR_LTLMES, commands->linebuf);
return -1;
}
}
*--tp = '\0';
if ((lpt = search(commands)) != NULL) {
if (lpt->address) {
command_errf(commands, SEDERR_DLMES, commands->linebuf);
return -1;
}
dechain(lpt, commands->rep);
} else {
commands->lab->chain = 0;
lpt = commands->lab;
if (++commands->lab >= commands->labend) {
command_errf(commands, SEDERR_TMLMES, commands->linebuf);
return -1;
}
}
lpt->address = commands->rep;
commands->rep->ad1 = p;
continue;
case 'a':
commands->rep->command = ACOM;
if (commands->rep->ad2) {
command_errf(commands, SEDERR_AD1MES, commands->linebuf);
return -1;
}
if (*commands->cp == '\\')
commands->cp++;
if (*commands->cp++ != '\n') {
command_errf(commands, SEDERR_CGMES, commands->linebuf);
return -1;
}
commands->rep->re1 = p;
p = text(commands, commands->rep->re1, commands->reend);
if (p == NULL)
return -1;
break;
case 'c':
commands->rep->command = CCOM;
if (*commands->cp == '\\') commands->cp++;
if (*commands->cp++ != ('\n')) {
command_errf(commands, SEDERR_CGMES, commands->linebuf);
return -1;
}
commands->rep->re1 = p;
p = text(commands, commands->rep->re1, commands->reend);
if (p == NULL)
return -1;
break;
case 'i':
commands->rep->command = ICOM;
if (commands->rep->ad2) {
command_errf(commands, SEDERR_AD1MES, commands->linebuf);
return -1;
}
if (*commands->cp == '\\') commands->cp++;
if (*commands->cp++ != ('\n')) {
command_errf(commands, SEDERR_CGMES, commands->linebuf);
return -1;
}
commands->rep->re1 = p;
p = text(commands, commands->rep->re1, commands->reend);
if (p == NULL)
return -1;
break;
case 'g':
commands->rep->command = GCOM;
break;
case 'G':
commands->rep->command = CGCOM;
break;
case 'h':
commands->rep->command = HCOM;
break;
case 'H':
commands->rep->command = CHCOM;
break;
case 't':
commands->rep->command = TCOM;
goto jtcommon;
case 'b':
commands->rep->command = BCOM;
jtcommon:
while (*commands->cp++ == ' ');
commands->cp--;
if (*commands->cp == '\0') {
if ((pt = commands->labtab->chain) != NULL) {
while ((pt1 = pt->lb1) != NULL)
pt = pt1;
pt->lb1 = commands->rep;
} else
commands->labtab->chain = commands->rep;
break;
}
tp = commands->lab->asc;
while ((*tp++ = *commands->cp++))
if (tp >= &(commands->lab->asc[8])) {
command_errf(commands, SEDERR_LTLMES, commands->linebuf);
return -1;
}
commands->cp--;
*--tp = '\0';
if ((lpt = search(commands)) != NULL) {
if (lpt->address) {
commands->rep->lb1 = lpt->address;
} else {
pt = lpt->chain;
while ((pt1 = pt->lb1) != NULL)
pt = pt1;
pt->lb1 = commands->rep;
}
} else {
commands->lab->chain = commands->rep;
commands->lab->address = 0;
if (++commands->lab >= commands->labend) {
command_errf(commands, SEDERR_TMLMES, commands->linebuf);
return -1;
}
}
break;
case 'n':
commands->rep->command = NCOM;
break;
case 'N':
commands->rep->command = CNCOM;
break;
case 'p':
commands->rep->command = PCOM;
break;
case 'P':
commands->rep->command = CPCOM;
break;
case 'r':
commands->rep->command = RCOM;
if (commands->rep->ad2) {
command_errf(commands, SEDERR_AD1MES, commands->linebuf);
return -1;
}
if (*commands->cp++ != ' ') {
command_errf(commands, SEDERR_CGMES, commands->linebuf);
return -1;
}
commands->rep->re1 = p;
p = text(commands, commands->rep->re1, commands->reend);
if (p == NULL)
return -1;
break;
case 'd':
commands->rep->command = DCOM;
break;
case 'D':
commands->rep->command = CDCOM;
commands->rep->lb1 = commands->ptrspace;
break;
case 'q':
commands->rep->command = QCOM;
if (commands->rep->ad2) {
command_errf(commands, SEDERR_AD1MES, commands->linebuf);
return -1;
}
break;
case 'l':
commands->rep->command = LCOM;
break;
case 's':
commands->rep->command = SCOM;
commands->sseof = *commands->cp++;
commands->rep->re1 = p;
p = comple(commands, &compargs, (char *) 0, commands->rep->re1,
commands->reend, commands->sseof);
if (p == NULL)
return -1;
if (p == commands->rep->re1) {
if (op)
commands->rep->re1 = op;
else {
command_errf(commands, SEDERR_NRMES);
return -1;
}
} else
op = commands->rep->re1;
commands->rep->rhs = p;
p = compsub(commands, &compargs, commands->rep->rhs);
if ((p) == NULL)
return -1;
if (*commands->cp == 'g') {
commands->cp++;
commands->rep->gfl = 999;
} else if (commands->gflag)
commands->rep->gfl = 999;
if (*commands->cp >= '1' && *commands->cp <= '9') {
i = *commands->cp - '0';
commands->cp++;
while (1) {
ii = *commands->cp;
if (ii < '0' || ii > '9')
break;
i = i*10 + ii - '0';
if (i > 512) {
command_errf(commands, SEDERR_TOOBIG, commands->linebuf);
return -1;
}
commands->cp++;
}
commands->rep->gfl = i;
}
if (*commands->cp == 'p') {
commands->cp++;
commands->rep->pfl = 1;
}
if (*commands->cp == 'P') {
commands->cp++;
commands->rep->pfl = 2;
}
if (*commands->cp == 'w') {
commands->cp++;
if (*commands->cp++ != ' ') {
command_errf(commands, SEDERR_SMMES, commands->linebuf);
return -1;
}
if (text(commands, fnamebuf, &fnamebuf[APR_PATH_MAX-1]) == NULL) {
command_errf(commands, SEDERR_FNTL, commands->linebuf);
return -1;
}
for (i = commands->nfiles - 1; i >= 0; i--)
if (strcmp(fnamebuf,commands->fname[i]) == 0) {
commands->rep->findex = i;
goto done;
}
if (commands->nfiles >= NWFILES) {
command_errf(commands, SEDERR_TMWFMES);
return -1;
}
commands->fname[commands->nfiles] =
apr_pstrdup(commands->pool, fnamebuf);
if (commands->fname[commands->nfiles] == NULL) {
command_errf(commands, SEDERR_OOMMES);
return -1;
}
commands->rep->findex = commands->nfiles++;
}
break;
case 'w':
commands->rep->command = WCOM;
if (*commands->cp++ != ' ') {
command_errf(commands, SEDERR_SMMES, commands->linebuf);
return -1;
}
if (text(commands, fnamebuf, &fnamebuf[APR_PATH_MAX-1]) == NULL) {
command_errf(commands, SEDERR_FNTL, commands->linebuf);
return -1;
}
for (i = commands->nfiles - 1; i >= 0; i--)
if (strcmp(fnamebuf, commands->fname[i]) == 0) {
commands->rep->findex = i;
goto done;
}
if (commands->nfiles >= NWFILES) {
command_errf(commands, SEDERR_TMWFMES);
return -1;
}
if ((commands->fname[commands->nfiles] =
apr_pstrdup(commands->pool, fnamebuf)) == NULL) {
command_errf(commands, SEDERR_OOMMES);
return -1;
}
commands->rep->findex = commands->nfiles++;
break;
case 'x':
commands->rep->command = XCOM;
break;
case 'y':
commands->rep->command = YCOM;
commands->sseof = *commands->cp++;
commands->rep->re1 = p;
p = ycomp(commands, commands->rep->re1);
if (p == NULL)
return -1;
break;
}
done:
commands->rep = alloc_reptr(commands);
commands->rep->ad1 = p;
if (*commands->cp++ != '\0') {
if (commands->cp[-1] == ';')
goto comploop;
command_errf(commands, SEDERR_CGMES, commands->linebuf);
return -1;
}
}
commands->rep->command = 0;
commands->lastre = op;
return 0;
}
static char *compsub(sed_commands_t *commands,
sed_comp_args *compargs, char *rhsbuf)
{
char *p, *q;
p = rhsbuf;
q = commands->cp;
for(;;) {
if(p > &commands->respace[RESIZE-1]) {
command_errf(commands, SEDERR_TMMES, commands->linebuf);
return NULL;
}
if((*p = *q++) == '\\') {
p++;
if(p > &commands->respace[RESIZE-1]) {
command_errf(commands, SEDERR_TMMES, commands->linebuf);
return NULL;
}
*p = *q++;
if(*p > compargs->nbra + '0' && *p <= '9') {
command_errf(commands, SEDERR_DOORNG, commands->linebuf);
return NULL;
}
p++;
continue;
}
if(*p == commands->sseof) {
*p++ = '\0';
commands->cp = q;
return(p);
}
if(*p++ == '\0') {
command_errf(commands, SEDERR_EDMOSUB, commands->linebuf);
return NULL;
}
}
}
/*
* rline
*/
static int rline(sed_commands_t *commands, apr_file_t *fin,
char *lbuf, char *lbend)
{
char *p;
const char *q;
int t;
apr_size_t bytes_read;
p = lbuf;
if(commands->eflag) {
if(commands->eflag > 0) {
commands->eflag = -1;
q = commands->earg;
while((t = *q++) != '\0') {
if(t == '\n') {
commands->saveq = q;
goto out1;
}
if (p < lbend)
*p++ = t;
if(t == '\\') {
if((t = *q++) == '\0') {
commands->saveq = NULL;
return(-1);
}
if (p < lbend)
*p++ = t;
}
}
commands->saveq = NULL;
out1:
if (p == lbend) {
command_errf(commands, SEDERR_CLTL);
return -1;
}
*p = '\0';
return(1);
}
if((q = commands->saveq) == 0) return(-1);
while((t = *q++) != '\0') {
if(t == '\n') {
commands->saveq = q;
goto out2;
}
if(p < lbend)
*p++ = t;
if(t == '\\') {
if((t = *q++) == '\0') {
commands->saveq = NULL;
return(-1);
}
if (p < lbend)
*p++ = t;
}
}
commands->saveq = NULL;
out2:
if (p == lbend) {
command_errf(commands, SEDERR_CLTL);
return -1;
}
*p = '\0';
return(1);
}
bytes_read = 1;
/* XXX extremely inefficient 1 byte reads */
while (apr_file_read(fin, &t, &bytes_read) != APR_SUCCESS) {
if(t == '\n') {
if (p == lbend) {
command_errf(commands, SEDERR_CLTL);
return -1;
}
*p = '\0';
return(1);
}
if (p < lbend)
*p++ = t;
if(t == '\\') {
bytes_read = 1;
if (apr_file_read(fin, &t, &bytes_read) != APR_SUCCESS) {
return -1;
}
if(p < lbend)
*p++ = t;
}
bytes_read = 1;
}
return(-1);
}
/*
* address
*/
static char *address(sed_commands_t *commands, char *expbuf,
apr_status_t* status)
{
char *rcp;
apr_int64_t lno;
sed_comp_args compargs;
*status = APR_SUCCESS;
if(*commands->cp == '$') {
if (expbuf > &commands->respace[RESIZE-2]) {
command_errf(commands, SEDERR_TMMES, commands->linebuf);
*status = APR_EGENERAL;
return NULL;
}
commands->cp++;
*expbuf++ = CEND;
*expbuf++ = CCEOF;
return(expbuf);
}
if (*commands->cp == '/' || *commands->cp == '\\' ) {
if ( *commands->cp == '\\' )
commands->cp++;
commands->sseof = *commands->cp++;
return(comple(commands, &compargs, (char *) 0, expbuf, commands->reend,
commands->sseof));
}
rcp = commands->cp;
lno = 0;
while(*rcp >= '0' && *rcp <= '9')
lno = lno*10 + *rcp++ - '0';
if(rcp > commands->cp) {
if (expbuf > &commands->respace[RESIZE-3]) {
command_errf(commands, SEDERR_TMMES, commands->linebuf);
*status = APR_EGENERAL;
return NULL;
}
*expbuf++ = CLNUM;
*expbuf++ = commands->nlno;
commands->tlno[commands->nlno++] = lno;
if(commands->nlno >= SED_NLINES) {
command_errf(commands, SEDERR_TMLNMES);
*status = APR_EGENERAL;
return NULL;
}
*expbuf++ = CCEOF;
commands->cp = rcp;
return(expbuf);
}
return(NULL);
}
/*
* text
*/
static char *text(sed_commands_t *commands, char *textbuf, char *tbend)
{
char *p, *q;
p = textbuf;
q = commands->cp;
#ifndef S5EMUL
/*
* Strip off indentation from text to be inserted.
*/
while(*q == '\t' || *q == ' ') q++;
#endif
for(;;) {
if(p > tbend)
return(NULL); /* overflowed the buffer */
if((*p = *q++) == '\\')
*p = *q++;
if(*p == '\0') {
commands->cp = --q;
return(++p);
}
#ifndef S5EMUL
/*
* Strip off indentation from text to be inserted.
*/
if(*p == '\n') {
while(*q == '\t' || *q == ' ') q++;
}
#endif
p++;
}
}
/*
* search
*/
static sed_label_t *search(sed_commands_t *commands)
{
sed_label_t *rp;
sed_label_t *ptr;
rp = commands->labtab;
ptr = commands->lab;
while (rp < ptr) {
if (strcmp(rp->asc, ptr->asc) == 0)
return rp;
rp++;
}
return 0;
}
/*
* ycomp
*/
static char *ycomp(sed_commands_t *commands, char *expbuf)
{
char c;
int cint; /* integer value of char c */
char *ep, *tsp;
int i;
char *sp;
ep = expbuf;
if(ep + 0377 > &commands->respace[RESIZE-1]) {
command_errf(commands, SEDERR_TMMES, commands->linebuf);
return NULL;
}
sp = commands->cp;
for(tsp = commands->cp; (c = *tsp) != commands->sseof; tsp++) {
if(c == '\\')
tsp++;
if(c == '\0' || c == '\n') {
command_errf(commands, SEDERR_EDMOSTR, commands->linebuf);
return NULL;
}
}
tsp++;
memset(ep, 0, 0400);
while((c = *sp++) != commands->sseof) {
c &= 0377;
if(c == '\\' && *sp == 'n') {
sp++;
c = '\n';
}
cint = (int) c;
if((ep[cint] = *tsp++) == '\\' && *tsp == 'n') {
ep[cint] = '\n';
tsp++;
}
if(ep[cint] == commands->sseof || ep[cint] == '\0') {
command_errf(commands, SEDERR_TSNTSS, commands->linebuf);
}
}
if(*tsp != commands->sseof) {
if(*tsp == '\0') {
command_errf(commands, SEDERR_EDMOSTR, commands->linebuf);
}
else {
command_errf(commands, SEDERR_TSNTSS, commands->linebuf);
}
return NULL;
}
commands->cp = ++tsp;
for(i = 0; i < 0400; i++)
if(ep[i] == 0)
ep[i] = i;
return(ep + 0400);
}
/*
* comple
*/
static char *comple(sed_commands_t *commands, sed_comp_args *compargs,
char *x1, char *ep, char *x3, char x4)
{
char *p;
p = sed_compile(commands, compargs, ep + 1, x3, x4);
if(p == ep + 1)
return(ep);
*ep = compargs->circf;
return(p);
}
/*
* alloc_reptr
*/
static sed_reptr_t *alloc_reptr(sed_commands_t *commands)
{
sed_reptr_t *var;
var = apr_pcalloc(commands->pool, sizeof(sed_reptr_t));
if (var == NULL) {
command_errf(commands, SEDERR_OOMMES);
return 0;
}
var->nrep = commands->nrep;
var->findex = -1;
commands->nrep++;
if (commands->ptrspace == NULL)
commands->ptrspace = var;
else
commands->ptrend->next = var;
commands->ptrend = var;
commands->labtab->address = var;
return var;
}