示例#1
0
文件: renderer.c 项目: Orc/ndialog
/*
 * addword() adds a word to the rendered page, breaking the line as
 * appropriate.
 */
void
addword(char *word)
{
    int siz = strlen(word);
    char *p;

    switch (state.doing) {
    case D_PRE:
	addstring((unsigned char*)word);
	break;
    case D_TITLE:
	state.page->titlelen += siz;
	state.page->title = realloc(state.page->title, state.page->titlelen+2);
	strcat(state.page->title, word);
	break;
    default:
	if (XP + siz > state.width)
	    breakline();
	if (state.style & St_CAPS) {
	    for (p=word; *p; ++p)
		*p = toupper(*p);
	}
	linestart();

	addstring((unsigned char*)word);
	XP += siz;
	break;
    }
    LASTWASSPACE = 0;
} /* addword */
示例#2
0
static int Openfile(TCHAR *outputFile, int selection)
{
	TCHAR filename[MAX_PATH+2] = _T("");
	TCHAR *title;

	TCHAR *filter, *tmp, *tmp1, *tmp2;
	tmp1 = TranslateT("Text Files (*.txt)");
	tmp2 = TranslateT("All Files");
	filter = tmp = (TCHAR*)_alloca((_tcslen(tmp1)+_tcslen(tmp2)+11)*sizeof(TCHAR));
	tmp = addstring(tmp, tmp1);
	tmp = addstring(tmp, _T("*.TXT"));
	tmp = addstring(tmp, tmp2);
	tmp = addstring(tmp, _T("*"));
	*tmp = 0;

	if (selection)
		title = TranslateT("Save selection to file");
	else
		title = TranslateT("Save log to file");

	OPENFILENAME ofn = {0};
	ofn.lStructSize = sizeof(ofn);
	ofn.hwndOwner = hwndConsole;
	ofn.lpstrFile = filename;
	ofn.lpstrFilter = filter;
	ofn.Flags = OFN_HIDEREADONLY | OFN_SHAREAWARE | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
	ofn.lpstrTitle = title;
	ofn.nMaxFile = MAX_PATH;
	ofn.lpstrDefExt = _T("txt");

	if (!GetSaveFileName(&ofn))
		return 0;
	_tcscpy(outputFile, filename);
	return 1;
}
示例#3
0
文件: asm.c 项目: 8l/go
void
adddynsym(Link *ctxt, LSym *s)
{
	LSym *d;
	int t;
	char *name;

	if(s->dynid >= 0)
		return;

	if(iself) {
		s->dynid = nelfsym++;

		d = linklookup(ctxt, ".dynsym", 0);

		name = s->extname;
		adduint32(ctxt, d, addstring(linklookup(ctxt, ".dynstr", 0), name));
		/* type */
		t = STB_GLOBAL << 4;
		if(s->cgoexport && (s->type&SMASK) == STEXT)
			t |= STT_FUNC;
		else
			t |= STT_OBJECT;
		adduint8(ctxt, d, t);
	
		/* reserved */
		adduint8(ctxt, d, 0);
	
		/* section where symbol is defined */
		if(s->type == SDYNIMPORT)
			adduint16(ctxt, d, SHN_UNDEF);
		else
			adduint16(ctxt, d, 1);
	
		/* value */
		if(s->type == SDYNIMPORT)
			adduint64(ctxt, d, 0);
		else
			addaddr(ctxt, d, s);
	
		/* size of object */
		adduint64(ctxt, d, s->size);
	
		if(!(s->cgoexport & CgoExportDynamic) && s->dynimplib && needlib(s->dynimplib)) {
			elfwritedynent(linklookup(ctxt, ".dynamic", 0), DT_NEEDED,
				addstring(linklookup(ctxt, ".dynstr", 0), s->dynimplib));
		}
	} else if(HEADTYPE == Hdarwin) {
		diag("adddynsym: missed symbol %s (%s)", s->name, s->extname);
	} else if(HEADTYPE == Hwindows) {
		// already taken care of
	} else {
		diag("adddynsym: unsupported binary format");
	}
}
示例#4
0
void MsgWin::updatedata() //обновить данные с сервера
{
    if (srv == NULL)
	return;
    if (srv->msgdom.empty())
    {
	clearcontent();
lastmsgno = 0;
	return;
    }
    Item* tmpmsgdom = srv->msgdom.hookptr();
    srv->msgdom.lock();
    if (lastmsgno == srv->lastmsgno) //в srv есть новые еще не отрисованные сообщения?
    {
	srv->msgdom.unlock();
	srv->msgdom.releaseptr(tmpmsgdom);
	return;
    }
    // === дополняем массив визуальных строк ===
    if (lastmsgno == 0)
        clearcontent(); //очищаем если отображение идет с начала
    Item* msgs = tmpmsgdom->findItem("msgs");
    if (msgs != NULL)
    {
	std::vector<Item*> mlist = msgs->getItems("msg");
	std::vector<Item*>::iterator it;
	for (it = mlist.begin(); it != mlist.end(); it++) //цикл по сообщениям
	{
	    Item* number = (*it)->findItem("seqno"); 	//номер текущего сообщения
	    if (number->getivalue()<=lastmsgno)
		continue; //пропускаем старые (уже добавленные ранее) сообщения
	    Item* body = (*it)->findItem("body"); 	//текст сообщения
	    Item* time = (*it)->findItem("time"); 	//время сообщения
	    if ((body != NULL)&&(time != NULL))
	    {
		time_t t = time->getivalue(); 		//время в секундах от 1.1.1970
		tm* ltime = localtime(&t);
		char tbuf[128];
		strftime(tbuf, sizeof(tbuf),"%-e %b %-k:%M",ltime);
		Item* project = (*it)->findItem("project");
		std::string sproject = "_no_";
		if (project != NULL)
		    sproject = project->getsvalue();
		addstring(getcolorpair(COLOR_CYAN,COLOR_BLACK) /*| A_BOLD*/,"#%d %s ", number->getivalue(), tbuf); //номер и время сообщения
		content.back()->append(getcolorpair(COLOR_YELLOW,COLOR_BLACK),"%s",sproject.c_str()); //добавить имя проекта другим цветом
		addstring(getcolorpair(COLOR_WHITE,COLOR_BLACK), "%s", body->getsvalue()); //само сообщение
	    }
	}
    }
    lastmsgno = srv->lastmsgno;
    //поскольку есть новые сообщения, то делаем автоскроллинг в конец
    setautoscroll(true);
    srv->msgdom.unlock();
    srv->msgdom.releaseptr(tmpmsgdom);
}
TStringID TStaticTemplateMatcher::AddTemplate(const std::string &templatestr) {
	if (used) 
		throw std::logic_error("AddTemplate after MatchStream");
	addstring(templatestr,template_lengths.size());
	template_lengths.push_back(templatestr.length());
	return template_lengths.size() - 1;
}
示例#6
0
void
addstrdata(char *name, char *value)
{
	LSym *s, *sp;
	char *p;
	uchar reachable;

	p = smprint("%s.str", name);
	sp = linklookup(ctxt, p, 0);
	free(p);
	addstring(sp, value);
	sp->type = SRODATA;

	s = linklookup(ctxt, name, 0);
	s->size = 0;
	s->dupok = 1;
	reachable = s->reachable;
	addaddr(ctxt, s, sp);
	adduint32(ctxt, s, strlen(value));
	if(PtrSize == 8)
		adduint32(ctxt, s, 0);  // round struct to pointer width

	// addstring, addaddr, etc., mark the symbols as reachable.
	// In this case that is not necessarily true, so stick to what
	// we know before entering this function.
	s->reachable = reachable;
	sp->reachable = reachable;
}
示例#7
0
unsigned int
mnt_mount(char *dir, struct cookie *pfh)
{
    struct pbuf *pbuf, *ret;
    int status;

    pbuf = initbuf(MNT_NUMBER, MNT_VERSION, MNTPROC_MNT);

    addstring(pbuf, dir);
    
    ret = rpc_call(pbuf, mount_port);

	 if (ret == 0) {
		 debug( "mount call failed :(\n" );
		 return 1;
	 }

    /* now we do some stuff :) */
    getfrombuf(ret, (char*) &status, sizeof(status));

	 if (status != 0) {
		 debug( "Could not mount %s, %d!\n", dir, status );
		 return 1;
	 }

	 debug("All seems good for mount: %s!\n", dir);

    getfrombuf(ret, (char*) pfh, sizeof(struct cookie));

    return 0;
}
示例#8
0
static void inittable(int orgcsize, struct local_data *data)
{
int f;
int numcols=(1<<(orgcsize-1));

for(f=0;f<REALMAXSTR;f++)
  {
  data->st_chr[f]=UNUSED;
  data->st_ptr[f]=UNUSED;
  data->st_ptr1st[f]=UNUSED;
  }

for(f=0;f<4096;f++)
  data->st_oldverhashlinks[f]=UNUSED;


if(data->oldver)
  {
  data->st_last=-1;		/* since it's a counter, when static */
  for(f=0;f<256;f++)
    addstring(0xffff,f,data);
  }
else
  {
  for(f=0;f<numcols;f++)
    data->st_chr[f]=f;
  data->st_last=numcols-1;      /* last occupied slot */

  if (data->quirk & NOMARCH_QUIRK_START101)	/* CM: Digital symphony quirk */
    data->st_last++;
  }
}
示例#9
0
文件: asm.c 项目: machinaut/go
void
adddynlib(char *lib)
{
	Sym *s;
	
	if(!needlib(lib))
		return;
	
	if(iself) {
		s = lookup(".dynstr", 0);
		if(s->size == 0)
			addstring(s, "");
		elfwritedynent(lookup(".dynamic", 0), DT_NEEDED, addstring(s, lib));
	} else {
		diag("adddynlib: unsupported binary format");
	}
}
示例#10
0
文件: l_string.c 项目: Omer80/wimps
static void*  smpl_emit(varptr ex)
{longstrptr   ans;
 char     s[STRSIZ];
 int      k, bt, nv, deg;
 int      star;
 varptr       ex_, exbeg;

   if (ex == NULL) return NULL;

   if (ex->sgn == '-')
   {
      ex_ = ex;

      while (ex_->next != NULL && ex_->next->sgn == '-')
      ex_ = ex_->next;

      if (ex_->next != NULL)
      {
         exbeg = ex_->next;
         ex_->next = exbeg->next;
         exbeg->next = ex;
         ex = exbeg;
      }
      
   }

   ans = (longstrptr)m_alloc(sizeof(longstr));
   ans->len = 0; 
   while (ex != NULL) 
   { 
      sprintf(s,"%c",ex->sgn);       
      star = (strcmp((ex->coef)->name,"1") != 0); 
      if (star || ex->vars[0] == 0) strcat(s,(ex->coef)->name); 
      if (ex->vars[0] != 0) 
      { 
         bt = (ex->vars[0]); 
         deg = 1; 
         for (k = 1; ex->vars[k]; k++) 
         { 
            nv = (ex->vars[k]); 
            if (bt != nv) 
            {
               if (star) strcat(s,"*"); else star = 1;     
               strcat(s,writevardeg(bt,deg)); 
               deg = 1; 
               bt = nv; 
            } 
            else ++(deg); 
         } 
         if (star) strcat(s,"*");  else  star = 1;      
         strcat(s,writevardeg(bt,deg)); 
      } 
      addstring(ans,s); 
      ex = ex->next; 
   } 
   return (void*) ans; 
}
示例#11
0
void
adddynlib(char *lib)
{
	LSym *s;
	
	if(!needlib(lib))
		return;
	
	if(iself) {
		s = linklookup(ctxt, ".dynstr", 0);
		if(s->size == 0)
			addstring(s, "");
		elfwritedynent(linklookup(ctxt, ".dynamic", 0), DT_NEEDED, addstring(s, lib));
	} else if(HEADTYPE == Hdarwin) {
		machoadddynlib(lib);
	} else {
		diag("adddynlib: unsupported binary format");
	}
}
示例#12
0
int env_addvar( env_h env, env_h from_env, char *var_name )
{
   char *var_string = env_lookup( from_env, var_name ) ;

   if ( var_string == NULL )
   {
      env_errno = ENV_EBADVAR ;
      return( ENV_ERR ) ;
   }

   return( addstring( env, var_string, strlen( var_name ) ) ) ;
}
示例#13
0
int env_addstr( env_h env, char *var_string )
{
   char *p = strchr( var_string, '=' ) ;

   if ( p == NULL )
   {
      env_errno = ENV_EBADSTRING ;
      return( ENV_ERR ) ;
   }

   return( addstring( env, var_string, (unsigned int)(p-var_string) ) ) ;
}
示例#14
0
文件: local.c 项目: newgenius/LiteBSD
/*
 * Create a reference for a TLS variable.
 * This is the "General dynamic" version.
 */
static NODE *
tlspic(NODE *p)
{
	NODE *q, *r, *s;
	char *s1, *s2;

	/*
	 * .byte   0x66
	 * leaq x@TLSGD(%rip),%rdi
	 * .word   0x6666
	 * rex64
	 * call __tls_get_addr@PLT
	 */

	/* Need the .byte stuff around.  Why? */
	/* Use inline assembler */
	q = mkx("%rdx", bcon(0));
	q = cmop(q, mkx("%rcx", bcon(0)));
	q = cmop(q, mkx("%rsi", bcon(0)));
	q = cmop(q, mkx("%rdi", bcon(0)));
	q = cmop(q, mkx("%r8", bcon(0)));
	q = cmop(q, mkx("%r9", bcon(0)));
	q = cmop(q, mkx("%r10", bcon(0)));
	q = cmop(q, mkx("%r11", bcon(0)));

	s = ccopy(r = tempnode(0, INCREF(p->n_type), p->n_df, p->n_ap));
	r = mkx("=a", r);
	r = block(XASM, r, q, INT, 0, 0);

	/* Create the magic string */
	s1 = ".byte 0x66\n\tleaq ";
	s2 = "@TLSGD(%%rip),%%rdi\n"
	    "\t.word 0x6666\n\trex64\n\tcall __tls_get_addr@PLT";
	if (attr_find(p->n_sp->sap, ATTR_SONAME) == NULL) {
		p->n_sp->sap = attr_add(p->n_sp->sap, attr_new(ATTR_SONAME, 1));
		p->n_sp->sap->sarg(0) = p->n_sp->sname;
	}
	r->n_name = addstring(mk3str(s1,
	    attr_find(p->n_sp->sap, ATTR_SONAME)->sarg(0), s2));

	r = block(COMOP, r, s, INCREF(p->n_type), p->n_df, p->n_ap);
	r = buildtree(UMUL, r, NIL);
	tfree(p);
	return r;
}
示例#15
0
文件: l_string.c 项目: Omer80/wimps
static void   addstring(longstrptr longs,char* s)
{
 int i,l,ll;
 char name[STRSIZ];
   ll = longs->len;
   l  = strlen(s);
   if (ll + l > buffsize)
   {
      sprintf(name,"tmp[%d]",tmpNameNum++);
      writelongstr(name,longs);
      longs->len = 0;
      addstring(longs,name);
      ll = longs->len;
   }
   
   for (i = 0; i < l; i++) longs->txt[ll + i] = s[i];
   longs->len += l;
}
示例#16
0
文件: data.c 项目: pipul/lab
void
addstrdata(char *name, char *value)
{
	Sym *s, *sp;
	char *p;
	
	p = smprint("%s.str", name);
	sp = lookup(p, 0);
	free(p);
	addstring(sp, value);

	s = lookup(name, 0);
	s->dupok = 1;
	addaddr(s, sp);
	adduint32(s, strlen(value));
	if(PtrSize == 8)
		adduint32(s, 0);  // round struct to pointer width
}
示例#17
0
/* remove a file named 'name' in directory 'cwd' */
int
nfs_remove(struct cookie *cwd, char *name, 
       void (*func) (uintptr_t, int), uintptr_t token)
{
    struct pbuf *pbuf;

    /* now the user data struct is setup, do some call stuff! */
    pbuf = initbuf(NFS_NUMBER, NFS_VERSION, NFSPROC_REMOVE);
    
    /* put in the fhandle */
    addtobuf(pbuf, (char*) cwd, sizeof(struct cookie));
    
    /* put in the name */
    addstring(pbuf, name);
    
    /* send it! */
    return rpc_send(pbuf, nfs_port, nfs_remove_cb, func, token);
}
示例#18
0
int lunascan::addtoken(const char *string,unsigned int id,int info)
   {
   int serial;

   init();

   serial=getstring(string);

   if (serial!=LUNA_UNKNOWN)
      {
      SCANNERMSG("identifier already defined");
      return(LUNA_UNKNOWN);
      }

   serial=addstring(string,id);

   POOL[serial].info=info;

   return(serial);
   }
示例#19
0
int
nfs_create(struct cookie *fh, char *name, sattr_t *sat,
     void (*func) (uintptr_t, int, struct cookie *, fattr_t *),
     uintptr_t token)
{
    struct pbuf *pbuf;
    
    /* now the user data struct is setup, do some call stuff! */
    pbuf = initbuf(NFS_NUMBER, NFS_VERSION, NFSPROC_CREATE);

    /* put in the fhandle */
    addtobuf(pbuf, (char*) fh, sizeof(struct cookie));
    
    /* put in the name */
    addstring(pbuf, name);
    
    addtobuf(pbuf, (char*) sat, sizeof(sattr_t));

    return rpc_send(pbuf, nfs_port, nfs_create_cb, func, token);
}
示例#20
0
文件: data.c 项目: hfeeki/golang
void
addstrdata(char *name, char *value)
{
	Sym *s, *sp;
	char *p;

	p = smprint("%s.str", name);
	sp = lookup(p, 0);
	free(p);
	addstring(sp, value);

	s = lookup(name, 0);
	s->size = 0;
	s->dupok = 1;
	addaddr(s, sp);
	adduint32(s, strlen(value));
	if(PtrSize == 8)
		adduint32(s, 0);  // round struct to pointer width

	// in case reachability has already been computed
	sp->reachable = s->reachable;
}
示例#21
0
文件: main.c 项目: arik181/myshell
int main(int argc, char ** argv)
{
	unsigned state = DEFAULT;
	unsigned * stateptr = &state;
	listptr historyptr;

	initialize(argc,argv,stateptr,&historyptr);

	char inputstring[MAXLINESIZE];
	char * strptr = &inputstring[0];

	/*** Main loop: 
	 * Print a prompt, 
	 * get input, 
	 * tokenize ***/
	while(!feof(stdin) && !(*stateptr & QUIT))
	{
        prettyprompt();
        getinput(inputstring);

		/*** If the user simply hits return, do nothing. ***/
		if (inputstring[0] != '\n')
		{
			/*** Otherwise, deal with input ***/
			handleinput(strptr,stateptr,historyptr);

			chomp(inputstring);

			/*** Add the string to history ***/
			/*** If there was no history error ***/
			if (NO_HISTERROR)
				addstring(inputstring,historyptr);
		}
	}

	cleanup(historyptr);
	return 0;
}
示例#22
0
static void cexp(JF, js_Ast *exp)
{
	int then, end;
	int n;

	switch (exp->type) {
	case EXP_STRING: emitstring(J, F, OP_STRING, exp->string); break;
	case EXP_NUMBER: emitnumber(J, F, exp->number); break;
	case EXP_UNDEF: emit(J, F, OP_UNDEF); break;
	case EXP_NULL: emit(J, F, OP_NULL); break;
	case EXP_TRUE: emit(J, F, OP_TRUE); break;
	case EXP_FALSE: emit(J, F, OP_FALSE); break;
	case EXP_THIS: emit(J, F, OP_THIS); break;

	case EXP_REGEXP:
		emit(J, F, OP_NEWREGEXP);
		emitraw(J, F, addstring(J, F, exp->string));
		emitraw(J, F, exp->number);
		break;

	case EXP_OBJECT:
		emit(J, F, OP_NEWOBJECT);
		cobject(J, F, exp->a);
		break;

	case EXP_ARRAY:
		emit(J, F, OP_NEWARRAY);
		carray(J, F, exp->a);
		break;

	case EXP_FUN:
		emitfunction(J, F, newfun(J, exp->a, exp->b, exp->c, 0));
		break;

	case EXP_IDENTIFIER:
		emitlocal(J, F, OP_GETLOCAL, OP_GETVAR, exp);
		break;

	case EXP_INDEX:
		cexp(J, F, exp->a);
		cexp(J, F, exp->b);
		emit(J, F, OP_GETPROP);
		break;

	case EXP_MEMBER:
		cexp(J, F, exp->a);
		emitstring(J, F, OP_GETPROP_S, exp->b->string);
		break;

	case EXP_CALL:
		ccall(J, F, exp->a, exp->b);
		break;

	case EXP_NEW:
		cexp(J, F, exp->a);
		n = cargs(J, F, exp->b);
		emit(J, F, OP_NEW);
		emitraw(J, F, n);
		break;

	case EXP_DELETE:
		cdelete(J, F, exp->a);
		break;

	case EXP_PREINC:
		cassignop1(J, F, exp->a);
		emit(J, F, OP_INC);
		cassignop2(J, F, exp->a, 0);
		break;

	case EXP_PREDEC:
		cassignop1(J, F, exp->a);
		emit(J, F, OP_DEC);
		cassignop2(J, F, exp->a, 0);
		break;

	case EXP_POSTINC:
		cassignop1(J, F, exp->a);
		emit(J, F, OP_POSTINC);
		cassignop2(J, F, exp->a, 1);
		emit(J, F, OP_POP);
		break;

	case EXP_POSTDEC:
		cassignop1(J, F, exp->a);
		emit(J, F, OP_POSTDEC);
		cassignop2(J, F, exp->a, 1);
		emit(J, F, OP_POP);
		break;

	case EXP_VOID:
		cexp(J, F, exp->a);
		emit(J, F, OP_POP);
		emit(J, F, OP_UNDEF);
		break;

	case EXP_TYPEOF: ctypeof(J, F, exp->a); break;
	case EXP_POS: cunary(J, F, exp, OP_POS); break;
	case EXP_NEG: cunary(J, F, exp, OP_NEG); break;
	case EXP_BITNOT: cunary(J, F, exp, OP_BITNOT); break;
	case EXP_LOGNOT: cunary(J, F, exp, OP_LOGNOT); break;

	case EXP_BITOR: cbinary(J, F, exp, OP_BITOR); break;
	case EXP_BITXOR: cbinary(J, F, exp, OP_BITXOR); break;
	case EXP_BITAND: cbinary(J, F, exp, OP_BITAND); break;
	case EXP_EQ: cbinary(J, F, exp, OP_EQ); break;
	case EXP_NE: cbinary(J, F, exp, OP_NE); break;
	case EXP_STRICTEQ: cbinary(J, F, exp, OP_STRICTEQ); break;
	case EXP_STRICTNE: cbinary(J, F, exp, OP_STRICTNE); break;
	case EXP_LT: cbinary(J, F, exp, OP_LT); break;
	case EXP_GT: cbinary(J, F, exp, OP_GT); break;
	case EXP_LE: cbinary(J, F, exp, OP_LE); break;
	case EXP_GE: cbinary(J, F, exp, OP_GE); break;
	case EXP_INSTANCEOF: cbinary(J, F, exp, OP_INSTANCEOF); break;
	case EXP_IN: cbinary(J, F, exp, OP_IN); break;
	case EXP_SHL: cbinary(J, F, exp, OP_SHL); break;
	case EXP_SHR: cbinary(J, F, exp, OP_SHR); break;
	case EXP_USHR: cbinary(J, F, exp, OP_USHR); break;
	case EXP_ADD: cbinary(J, F, exp, OP_ADD); break;
	case EXP_SUB: cbinary(J, F, exp, OP_SUB); break;
	case EXP_MUL: cbinary(J, F, exp, OP_MUL); break;
	case EXP_DIV: cbinary(J, F, exp, OP_DIV); break;
	case EXP_MOD: cbinary(J, F, exp, OP_MOD); break;

	case EXP_ASS: cassign(J, F, exp); break;
	case EXP_ASS_MUL: cassignop(J, F, exp, OP_MUL); break;
	case EXP_ASS_DIV: cassignop(J, F, exp, OP_DIV); break;
	case EXP_ASS_MOD: cassignop(J, F, exp, OP_MOD); break;
	case EXP_ASS_ADD: cassignop(J, F, exp, OP_ADD); break;
	case EXP_ASS_SUB: cassignop(J, F, exp, OP_SUB); break;
	case EXP_ASS_SHL: cassignop(J, F, exp, OP_SHL); break;
	case EXP_ASS_SHR: cassignop(J, F, exp, OP_SHR); break;
	case EXP_ASS_USHR: cassignop(J, F, exp, OP_USHR); break;
	case EXP_ASS_BITAND: cassignop(J, F, exp, OP_BITAND); break;
	case EXP_ASS_BITXOR: cassignop(J, F, exp, OP_BITXOR); break;
	case EXP_ASS_BITOR: cassignop(J, F, exp, OP_BITOR); break;

	case EXP_COMMA:
		cexp(J, F, exp->a);
		emit(J, F, OP_POP);
		cexp(J, F, exp->b);
		break;

	case EXP_LOGOR:
		cexp(J, F, exp->a);
		emit(J, F, OP_DUP);
		end = emitjump(J, F, OP_JTRUE);
		emit(J, F, OP_POP);
		cexp(J, F, exp->b);
		label(J, F, end);
		break;

	case EXP_LOGAND:
		cexp(J, F, exp->a);
		emit(J, F, OP_DUP);
		end = emitjump(J, F, OP_JFALSE);
		emit(J, F, OP_POP);
		cexp(J, F, exp->b);
		label(J, F, end);
		break;

	case EXP_COND:
		cexp(J, F, exp->a);
		then = emitjump(J, F, OP_JTRUE);
		cexp(J, F, exp->c);
		end = emitjump(J, F, OP_JUMP);
		label(J, F, then);
		cexp(J, F, exp->b);
		label(J, F, end);
		break;

	default:
		jsC_error(J, exp, "unknown expression: (%s)", jsP_aststring(exp->type));
	}
}
示例#23
0
static void emitstring(JF, int opcode, const char *str)
{
	emit(J, F, opcode);
	emitraw(J, F, addstring(J, F, str));
}
示例#24
0
/* XXX - There is an issue which will cause a failure if there are more than 16
  EXTRA_ELEMENTs.  This is a problem with the size of the data structure that
  is used to hold the metric information.
*/
static int
startElement_EXTRA_ELEMENT (void *data, const char *el, const char **attr)
{
    xmldata_t *xmldata = (xmldata_t *)data;
    int edge;
    struct xml_tag *xt;
    int i, name_off, value_off;
    Metric_t metric;
    char *name = getfield(xmldata->metric.strings, xmldata->metric.name);
    datum_t *rdatum;
    datum_t hashkey, hashval;
    datum_t *hash_datum = NULL;

    if (!xmldata->host_alive)
        return 0;

    /* Only keep extra element details if we are the authority on this cluster. */
    if (!authority_mode(xmldata))
        return 0;

    hashkey.data = (void*) name;
    hashkey.size =  strlen(name) + 1;

    hash_datum = hash_lookup (&hashkey, xmldata->host.metrics);
    if (!hash_datum)
        return 0;

    memcpy(&metric, hash_datum->data, hash_datum->size);
    datum_free(hash_datum);

    /* Check to make sure that we don't try to add more
        extra elements than the array can handle.
    */
    if (metric.ednameslen >= MAX_EXTRA_ELEMENTS)
    {
        debug_msg("Can not add more extra elements for [%s].  Capacity of %d reached[%s].",
                  name, MAX_EXTRA_ELEMENTS);
        return 0;
    }

    edge = metric.stringslen;

    name_off = value_off = -1;
    for(i = 0; attr[i]; i+=2)
    {
        xt = in_xml_list(attr[i], strlen(attr[i]));
        if (!xt)
            continue;
        switch (xt->tag)
        {
        case NAME_TAG:
            name_off = i;
            break;
        case VAL_TAG:
            value_off = i;
            break;
        default:
            break;
        }
    }

    if ((name_off >= 0) && (value_off >= 0))
    {
        const char *new_name = attr[name_off+1];
        const char *new_value = attr[value_off+1];

        metric.ednames[metric.ednameslen++] = addstring(metric.strings, &edge, new_name);
        metric.edvalues[metric.edvalueslen++] = addstring(metric.strings, &edge, new_value);

        metric.stringslen = edge;

        hashkey.data = (void*)name;
        hashkey.size =  strlen(name) + 1;

        /* Trim metric structure to the correct length. */
        hashval.size = sizeof(metric) - GMETAD_FRAMESIZE + metric.stringslen;
        hashval.data = (void*) &metric;

        /* Update full metric in cluster host table. */
        rdatum = hash_insert(&hashkey, &hashval, xmldata->host.metrics);
        if (!rdatum)
        {
            err_msg("Could not insert %s metric", name);
        }
        else
        {
            hash_t *summary = xmldata->source.metric_summary;
            Metric_t sum_metric;

            /* do not add every SPOOF_HOST element to the summary table.
               if the same metric is SPOOF'd on more than ~MAX_EXTRA_ELEMENTS hosts
               then its summary table is destroyed.
             */
            if ( strlen(new_name) == 10 && !strcasecmp(new_name, SPOOF_HOST) )
                return 0;

            /* only update summary if metric is in hash */
            hash_datum = hash_lookup(&hashkey, summary);

            if (hash_datum) {
                int found = FALSE;

                memcpy(&sum_metric, hash_datum->data, hash_datum->size);
                datum_free(hash_datum);

                for (i = 0; i < sum_metric.ednameslen; i++) {
                    char *chk_name = getfield(sum_metric.strings, sum_metric.ednames[i]);
                    char *chk_value = getfield(sum_metric.strings, sum_metric.edvalues[i]);

                    /* If the name and value already exists, skip adding the strings. */
                    if (!strcasecmp(chk_name, new_name) && !strcasecmp(chk_value, new_value)) {
                        found = TRUE;
                        break;
                    }
                }
                if (!found) {
                    edge = sum_metric.stringslen;
                    sum_metric.ednames[sum_metric.ednameslen++] = addstring(sum_metric.strings, &edge, new_name);
                    sum_metric.edvalues[sum_metric.edvalueslen++] = addstring(sum_metric.strings, &edge, new_value);
                    sum_metric.stringslen = edge;
                }

                /* Trim graph display sum_metric at (352, 208) now or when in startElement_EXTRA_ELEMENT
                metric structure to the correct length. Tricky. */
                hashval.size = sizeof(sum_metric) - GMETAD_FRAMESIZE + sum_metric.stringslen;
                hashval.data = (void*) &sum_metric;

                /* Update metric in summary table. */
                rdatum = hash_insert(&hashkey, &hashval, summary);
                if (!rdatum)
                    err_msg("Could not insert summary %s metric", name);
            }
        }
    }

    return 0;
}
示例#25
0
/* Populates a Metric_t structure from a list of XML metric attribute strings.
 * We need the type string here because we cannot be sure it comes before
 * the metric value in the attribute list.
 */
static void
fillmetric(const char** attr, Metric_t *metric, const char* type)
{
    int i;
    /* INV: always points to the next free byte in metric.strings buffer. */
    int edge = 0;
    struct type_tag *tt;
    struct xml_tag *xt;
    char *metricval, *p;

    /* For old versions of gmond. */
    metric->slope = -1;

    for(i = 0; attr[i] ; i+=2)
    {
        /* Only process the XML tags that gmetad is interested in */
        xt = in_xml_list (attr[i], strlen(attr[i]));
        if (!xt)
            continue;

        switch( xt->tag )
        {
        case SUM_TAG:
        case VAL_TAG:
            metricval = (char*) attr[i+1];

            tt = in_type_list(type, strlen(type));
            if (!tt) return;

            switch (tt->type)
            {
            case INT:
            case TIMESTAMP:
            case UINT:
            case FLOAT:
                metric->val.d = (double)
                                strtod(metricval, (char**) NULL);
                p = strrchr(metricval, '.');
                if (p) metric->precision = (short int) strlen(p+1);
                break;
            case STRING:
                /* We store string values in the 'valstr' field. */
                break;
            }
            metric->valstr = addstring(metric->strings, &edge, metricval);
            break;
        case TYPE_TAG:
            metric->type = addstring(metric->strings, &edge, attr[i+1]);
            break;
        case UNITS_TAG:
            metric->units = addstring(metric->strings, &edge, attr[i+1]);
            break;
        case TN_TAG:
            metric->tn = atoi(attr[i+1]);
            break;
        case TMAX_TAG:
            metric->tmax = atoi(attr[i+1]);
            break;
        case DMAX_TAG:
            metric->dmax = atoi(attr[i+1]);
            break;
        case SLOPE_TAG:
            metric->slope = addstring(metric->strings, &edge, attr[i+1]);
            break;
        case SOURCE_TAG:
            metric->source = addstring(metric->strings, &edge, attr[i+1]);
            break;
        case NUM_TAG:
            metric->num = atoi(attr[i+1]);
            break;
        default:
            break;
        }
    }
    metric->stringslen = edge;

    /* We are ok with growing metric values b/c we write to a full-sized
     * buffer in xmldata. */
}
示例#26
0
static int
startElement_METRIC(void *data, const char *el, const char **attr)
{
    xmldata_t *xmldata = (xmldata_t *)data;
    ganglia_slope_t slope = GANGLIA_SLOPE_UNSPECIFIED;
    struct xml_tag *xt;
    struct type_tag *tt;
    datum_t *hash_datum = NULL;
    datum_t *rdatum;
    datum_t hashkey, hashval;
    const char *name = NULL;
    const char *metricval = NULL;
    const char *type = NULL;
    int do_summary;
    int i, edge, carbon_ret;
    hash_t *summary;
    Metric_t *metric;

    if (!xmldata->host_alive ) return 0;

    /* Get name for hash key, and val/type for summaries. */
    for(i = 0; attr[i]; i+=2)
    {
        xt = in_xml_list(attr[i], strlen(attr[i]));
        if (!xt) continue;

        switch (xt->tag)
        {
        case NAME_TAG:
            name = attr[i+1];
            hashkey.data = (void*) name;
            hashkey.size =  strlen(name) + 1;
            break;
        case VAL_TAG:
            metricval = attr[i+1];
            break;
        case TYPE_TAG:
            type = attr[i+1];
            break;
        case SLOPE_TAG:
            slope = cstr_to_slope(attr[i+1]);
        default:
            break;
        }
    }

    metric = &(xmldata->metric);
    memset((void*) metric, 0, sizeof(*metric));

    /* Summarize all numeric metrics */
    do_summary = 0;
    tt = in_type_list(type, strlen(type));
    if (!tt) return 0;

    if (tt->type==INT || tt->type==UINT || tt->type==FLOAT)
        do_summary = 1;

    /* Only keep metric details if we are the authority on this cluster. */
    if (authority_mode(xmldata))
    {
        /* Save the data to a round robin database if the data source is alive
         */
        fillmetric(attr, metric, type);
        if (metric->dmax && metric->tn > metric->dmax)
            return 0;

        if (do_summary && !xmldata->ds->dead && !xmldata->rval)
        {
            debug_msg("Updating host %s, metric %s",
                      xmldata->hostname, name);
            if ( gmetad_config.write_rrds == 1 )
                xmldata->rval = write_data_to_rrd(xmldata->sourcename,
                                                  xmldata->hostname, name, metricval, NULL,
                                                  xmldata->ds->step, xmldata->source.localtime, slope);
            if (gmetad_config.carbon_server) // if the user has specified a carbon server, send the metric to carbon as well
                carbon_ret=write_data_to_carbon(xmldata->sourcename, xmldata->hostname, name, metricval,xmldata->source.localtime);
        }
        metric->id = METRIC_NODE;
        metric->report_start = metric_report_start;
        metric->report_end = metric_report_end;


        edge = metric->stringslen;
        metric->name = addstring(metric->strings, &edge, name);
        metric->stringslen = edge;

        /* Set local idea of T0. */
        metric->t0 = xmldata->now;
        metric->t0.tv_sec -= metric->tn;

        /* Trim metric structure to the correct length. */
        hashval.size = sizeof(*metric) - GMETAD_FRAMESIZE + metric->stringslen;
        hashval.data = (void*) metric;

        /* Update full metric in cluster host table. */
        rdatum = hash_insert(&hashkey, &hashval, xmldata->host.metrics);
        if (!rdatum)
        {
            err_msg("Could not insert %s metric", name);
        }
    }

    /* Always update summary for numeric metrics. */
    if (do_summary)
    {
        summary = xmldata->source.metric_summary;
        hash_datum = hash_lookup(&hashkey, summary);
        if (!hash_datum)
        {
            if (!authority_mode(xmldata))
            {
                metric = &(xmldata->metric);
                memset((void*) metric, 0, sizeof(*metric));
                fillmetric(attr, metric, type);
            }
            /* else we have already filled in the metric above. */
        }
        else
        {
            memcpy(&xmldata->metric, hash_datum->data, hash_datum->size);
            datum_free(hash_datum);
            metric = &(xmldata->metric);

            switch (tt->type)
            {
            case INT:
            case UINT:
            case FLOAT:
                metric->val.d += (double)
                                 strtod(metricval, (char**) NULL);
                break;
            default:
                break;
            }
        }

        metric->num++;
        metric->t0 = xmldata->now; /* tell cleanup thread we are using this */

        /* Trim metric structure to the correct length. Tricky. */
        hashval.size = sizeof(*metric) - GMETAD_FRAMESIZE + metric->stringslen;
        hashval.data = (void*) metric;

        /* Update metric in summary table. */
        rdatum = hash_insert(&hashkey, &hashval, summary);
        if (!rdatum) err_msg("Could not insert %s metric", name);
    }
    return 0;
}
示例#27
0
static int
startElement_HOST(void *data, const char *el, const char **attr)
{
    xmldata_t *xmldata = (xmldata_t *)data;
    datum_t *hash_datum = NULL;
    datum_t *rdatum;
    datum_t hashkey, hashval;
    struct xml_tag *xt;
    uint32_t tn=0;
    uint32_t tmax=0;
    uint32_t reported=0;
    const char *name = NULL;
    int edge;
    int i;
    Host_t *host;
    hash_t *hosts;

    /* Check if the host is up. */
    for (i = 0; attr[i]; i+=2)
    {
        xt = in_xml_list (attr[i], strlen(attr[i]));
        if (!xt) continue;

        if (xt->tag == REPORTED_TAG)
            reported = strtoul(attr[i+1], (char **)NULL, 10);
        else if (xt->tag == TN_TAG)
            tn = atoi(attr[i+1]);
        else if (xt->tag == TMAX_TAG)
            tmax = atoi(attr[i+1]);
        else if (xt->tag == NAME_TAG)
            name = attr[i+1];
    }

    /* Is this host alive? For pre-2.5.0, we use the 60-second
     * method, otherwise we use the host's TN and TMAX attrs.
     */
    xmldata->host_alive = (xmldata->old || !tmax) ?
                          abs(xmldata->source.localtime - reported) < 60 :
                          tn < tmax * 4;

    if (xmldata->host_alive)
        xmldata->source.hosts_up++;
    else
        xmldata->source.hosts_down++;

    /* Only keep host details if we are the authority on this cluster. */
    if (!authority_mode(xmldata))
        return 0;

    host = &(xmldata->host);

    /* Use node Name for hash key (Query processing
     * requires a name key).
     */
    xmldata->hostname = realloc(xmldata->hostname, strlen(name)+1);
    strcpy(xmldata->hostname, name);

    /* Convert name to lower case - host names can't be
     * case sensitive
     */
    /*for(i = 0; name[i] != 0; i++)
        xmldata->hostname[i] = tolower(name[i]);
    xmldata->hostname[i] = 0; */

    hashkey.data = (void*) name;
    hashkey.size =  strlen(name) + 1;

    hosts = xmldata->source.authority;
    hash_datum = hash_lookup (&hashkey, hosts);
    if (!hash_datum)
    {
        memset((void*) host, 0, sizeof(*host));

        host->id = HOST_NODE;
        host->report_start = host_report_start;
        host->report_end = host_report_end;

        /* Only create one hash table for the host's metrics. Not user/builtin
         * like gmond. */
        host->metrics = hash_create(DEFAULT_METRICSIZE);
        if (!host->metrics)
        {
            err_msg("Could not create metric hash for host %s", name);
            return 1;
        }
    }
    else
    {
        /* Copy the stored host data into our Host buffer in xmldata. */
        memcpy(host, hash_datum->data, hash_datum->size);
        datum_free(hash_datum);
    }

    /* Edge has the same invariant as in fillmetric(). */
    edge = 0;

    host->location = -1;
    host->tags = -1;
    host->reported = reported;
    host->tn = tn;
    host->tmax = tmax;
    /* sacerdoti: Host TN tracks what gmond sees. TN=0 when gmond received last
     * heartbeat from node. Works because clocks move at same speed, and TN is
     * a relative timespan. */
    host->t0 = xmldata->now;
    host->t0.tv_sec -= host->tn;

    /* We will store this host in the cluster's authority table. */
    for(i = 0; attr[i]; i+=2)
    {
        xt = in_xml_list (attr[i], strlen(attr[i]));
        if (!xt) continue;

        switch( xt->tag )
        {
        case IP_TAG:
            host->ip = addstring(host->strings, &edge, attr[i+1]);
            break;
        case DMAX_TAG:
            host->dmax = strtoul(attr[i+1], (char **)NULL, 10);
            break;
        case LOCATION_TAG:
            host->location = addstring(host->strings, &edge, attr[i+1]);
            break;
        case TAGS_TAG:
            host->tags = addstring(host->strings, &edge, attr[i+1]);
            break;
        case STARTED_TAG:
            host->started = strtoul(attr[i+1], (char **)NULL, 10);
            break;
        default:
            break;
        }
    }
    host->stringslen = edge;

    /* Trim structure to the correct length. */
    hashval.size = sizeof(*host) - GMETAD_FRAMESIZE + host->stringslen;
    hashval.data = host;

    /* We dont care if this is an insert or an update. */
    rdatum = hash_insert(&hashkey, &hashval, hosts);
    if (!rdatum) {
        err_msg("Could not insert host %s", name);
        return 1;
    }
    return 0;
}
示例#28
0
static int
startElement_CLUSTER(void *data, const char *el, const char **attr)
{
    xmldata_t *xmldata = (xmldata_t *)data;
    struct xml_tag *xt;
    datum_t *hash_datum = NULL;
    datum_t hashkey;
    const char *name = NULL;
    int edge;
    int i;
    Source_t *source;

    /* Get name for hash key */
    for(i = 0; attr[i]; i+=2)
    {
        xt = in_xml_list (attr[i], strlen(attr[i]));
        if (!xt) continue;

        if (xt->tag == NAME_TAG)
            name = attr[i+1];
    }

    /* Only keep cluster details if we are the authority on this cluster. */
    if (!authority_mode(xmldata))
        return 0;

    source = &(xmldata->source);

    xmldata->sourcename = realloc(xmldata->sourcename, strlen(name)+1);
    strcpy(xmldata->sourcename, name);
    hashkey.data = (void*) name;
    hashkey.size =  strlen(name) + 1;

    hash_datum = hash_lookup(&hashkey, xmldata->root);
    if (!hash_datum)
    {
        memset((void*) source, 0, sizeof(*source));

        /* Set the identity of this host. */
        source->id = CLUSTER_NODE;
        source->report_start = source_report_start;
        source->report_end = source_report_end;

        source->authority = hash_create(DEFAULT_CLUSTERSIZE);
        if (!source->authority)
        {
            err_msg("Could not create hash table for cluster %s", name);
            return 1;
        }
        if(gmetad_config.case_sensitive_hostnames == 0)
            hash_set_flags(source->authority, HASH_FLAG_IGNORE_CASE);

        source->metric_summary = hash_create(DEFAULT_METRICSIZE);
        if (!source->metric_summary)
        {
            err_msg("Could not create summary hash for cluster %s", name);
            return 1;
        }
        source->ds = xmldata->ds;

        /* Initialize the partial sum lock */
        source->sum_finished = (pthread_mutex_t *)
                               malloc(sizeof(pthread_mutex_t));
        pthread_mutex_init(source->sum_finished, NULL);

        /* Grab the "partial sum" mutex until we are finished summarizing. */
        pthread_mutex_lock(source->sum_finished);
    }
    else
    {
        memcpy(source, hash_datum->data, hash_datum->size);
        datum_free(hash_datum);

        /* We need this lock before zeroing metric sums. */
        pthread_mutex_lock(source->sum_finished);

        source->hosts_up = 0;
        source->hosts_down = 0;

        hash_foreach(source->metric_summary, zero_out_summary, NULL);
    }

    /* Edge has the same invariant as in fillmetric(). */
    edge = 0;

    source->owner = -1;
    source->latlong = -1;
    source->url = -1;
    /* Fill in cluster attributes. */
    for(i = 0; attr[i]; i+=2)
    {
        xt = in_xml_list (attr[i], strlen(attr[i]));
        if (!xt)
            continue;

        switch( xt->tag )
        {
        case OWNER_TAG:
            source->owner = addstring(source->strings, &edge, attr[i+1]);
            break;
        case LATLONG_TAG:
            source->latlong = addstring(source->strings,
                                        &edge, attr[i+1]);
            break;
        case URL_TAG:
            source->url = addstring(source->strings, &edge, attr[i+1]);
            break;
        case LOCALTIME_TAG:
            source->localtime = strtoul(attr[i+1],
                                        (char **) NULL, 10);
            break;
        default:
            break;
        }
    }
    source->stringslen = edge;
    return 0;
}
示例#29
0
static int
startElement_GRID(void *data, const char *el, const char **attr)
{
    xmldata_t *xmldata = (xmldata_t *)data;
    struct xml_tag *xt;
    datum_t *hash_datum = NULL;
    datum_t hashkey;
    const char *name = NULL;
    int edge;
    int i;
    Source_t *source;

    /* In non-scalable mode, we ignore GRIDs. */
    if (!gmetad_config.scalable_mode)
        return 0;

    /* We do not keep info on nested grids. */
    if (authority_mode(xmldata))
    {
        /* Get name for hash key */
        for(i = 0; attr[i]; i+=2)
        {
            xt = in_xml_list (attr[i], strlen(attr[i]));
            if (!xt) continue;

            if (xt->tag == NAME_TAG)
            {
                name = attr[i+1];
                xmldata->sourcename =
                    realloc(xmldata->sourcename, strlen(name)+1);
                strcpy(xmldata->sourcename, name);
                hashkey.data = (void*) name;
                hashkey.size =  strlen(name) + 1;
            }
        }

        source = &(xmldata->source);

        /* Query the hash table for this cluster */
        hash_datum = hash_lookup(&hashkey, xmldata->root);
        if (!hash_datum)
        {   /* New Cluster */
            memset((void*) source, 0, sizeof(*source));

            source->id = GRID_NODE;
            source->report_start = source_report_start;
            source->report_end = source_report_end;

            source->metric_summary = hash_create(DEFAULT_METRICSIZE);
            if (!source->metric_summary)
            {
                err_msg("Could not create summary hash for cluster %s",
                        name);
                return 1;
            }
            source->ds = xmldata->ds;

            /* Initialize the partial sum lock */
            source->sum_finished = (pthread_mutex_t *)
                                   malloc(sizeof(pthread_mutex_t));
            pthread_mutex_init(source->sum_finished, NULL);

            /* Grab the "partial sum" mutex until we are finished
             * summarizing. */
            pthread_mutex_lock(source->sum_finished);
        }
        else
        {   /* Found Cluster. Put into our Source buffer in xmldata. */
            memcpy(source, hash_datum->data, hash_datum->size);
            datum_free(hash_datum);

            /* Grab the "partial sum" mutex until we are finished
             * summarizing. Needs to be done asap.*/
            pthread_mutex_lock(source->sum_finished);

            source->hosts_up = 0;
            source->hosts_down = 0;

            hash_foreach(source->metric_summary, zero_out_summary, NULL);
        }

        /* Edge has the same invariant as in fillmetric(). */
        edge = 0;

        /* Fill in grid attributes. */
        for(i = 0; attr[i]; i+=2)
        {
            xt = in_xml_list(attr[i], strlen(attr[i]));
            if (!xt)
                continue;

            switch( xt->tag )
            {
            case AUTHORITY_TAG:
                source->authority_ptr = addstring(source->strings,
                                                  &edge, attr[i+1]);
                break;
            case LOCALTIME_TAG:
                source->localtime = strtoul(attr[i+1],
                                            (char **) NULL, 10);
                break;
            default:
                break;
            }
        }
        source->stringslen = edge;
    }

    /* Must happen after all processing of this tag. */
    xmldata->grid_depth++;
    debug_msg("Found a <GRID>, depth is now %d", xmldata->grid_depth);

    return 0;
}
示例#30
0
文件: l_string.c 项目: Omer80/wimps
static void*  gorner(char* s,longstrptr pmult,longstrptr psum)
{
 char name[STRSIZ], name2[STRSIZ];
 longstrptr   ans;
 void*      pchange;

   if (pmult == NULL) return (void*)psum;
   ans = (longstrptr)m_alloc(sizeof(longstr));
   ans->len = 0;
   addstring(ans,s);

   if (3 + ans->len + pmult->len > buffsize)
   {
      sprintf(name,"tmp[%d]",tmpNameNum++);
      writelongstr(name,pmult);
      addstring(ans,"*"); addstring(ans,name);
   }
   else
   {
      if (pmult->txt[0] == '+')
      {
         pmult->txt[0] = '(';
         addstring(ans,"*");
      }
      else  addstring(ans,"*(");
     
      memcpy(&(ans->txt[ans->len]),pmult->txt,pmult->len);
      ans->len += pmult->len;
      addstring(ans,")");
   }
   free(pmult);

   if (psum == NULL) return (void*)ans;
   if (ans->len + psum->len > buffsize)
   {
      sprintf(name,"tmp[%d]",tmpNameNum++);
      if (ans->len > psum->len)
      {
         pchange = (void*)ans;
         ans = psum;
         psum = (longstrptr)pchange;
      }
      writelongstr(name,psum);
      if (ans->len + strlen(name) >= buffsize)
      {
         sprintf(name2,"tmp[%d]",tmpNameNum++);
         writelongstr(name2,ans);
         ans->len = 0;
         addstring(ans,"+");addstring(ans,name);
         addstring(ans,"+");addstring(ans,name2);
      }
      else { addstring(ans,"+"); addstring(ans,name);}
          
   }
   else
   {
      memcpy(&(ans->txt[ans->len]),psum->txt,psum->len);
      ans->len += psum->len;
   }
   free(psum);
   return (void*)ans;
}