Beispiel #1
0
Value *
read_string(Globals *g)
{
   int strpos = 0;
   Value *v;
   char c;

#define ADD_CHAR(c)	\
   if (strpos >= g->strbuflen) \
      expand_strbuf(g);		\
   g->strbuf[strpos++] = (c)

   while (1) {
      switch (PEEK_CHAR(g)) {
       case '\"':
	 NEXT_CHAR(g);
	 v = ALLOC_VALUE();
	 v->tag = string;
	 v->value.s.length = strpos;
	 v->value.s.string = (char *) malloc(v->value.s.length);
	 bcopy(g->strbuf, v->value.s.string, v->value.s.length);
	 return v;
	 break;
       case '\\':
	 NEXT_CHAR(g);
	 if (read_escape(g, &c))
	    ADD_CHAR(c);
	 break;
       default:
	 ADD_CHAR(PEEK_CHAR(g));
	 NEXT_CHAR(g);
	 break;
      }
   }
}
Beispiel #2
0
char *prepare_str_old (char *x) {
  char *s = prep_buf;
  int i=0, j=0;

  while (x[i] && !is_letter (x[i])) {
    i++;
  }

  while (x[i]) {
    while (is_letter (x[i])) {
      ADD_CHAR(x[i++]);
    }
    while (x[i] && !is_letter (x[i])) {
      i++;
    }
    if (!x[i])
    {
      ADD_CHAR('+');
      break;
    }
    ADD_CHAR('+');
  }

  ADD_CHAR(0);

  char *res = dl_malloc (j);
  if (res == NULL) {
    return res;
  }
  memcpy (res, prep_buf, j);

  return res;
}
Beispiel #3
0
/**
 * Converts signed 32b integer value to string
 * @param val   integer value
 * @param str   converted textual representation
 * @param len   string buffer length
 * @param base  output base
 * @return number of bytes written to str (without '\0')
 */
size_t SCPI_LongToStr(int32_t val, char * str, size_t len, int8_t base) {
    const char digits[] = "0123456789ABCDEF";

#define ADD_CHAR(c) if (pos < len) str[pos++] = (c)
    uint32_t x = 0;
    int_fast8_t digit;
    size_t pos = 0;
    uint32_t uval = val;

    if (uval == 0) {
        ADD_CHAR('0');
    } else {

        switch (base) {
            case 2: 
                x = 0x80000000L;
                break;
            case 8:
                x = 0x40000000L;
                break;
            case 10:
                x = 1000000000L;
                break;
            case 0x10:
                x = 0x10000000L;
                break;
            default:
                x = 1000000000L;
                base = 10;
                break;
        }

        // add sign for numbers in base 10
        if ((val < 0) && (base == 10)) {
            uval = -val;
            ADD_CHAR('-');
        }

        // remove leading zeros
        while ((uval / x) == 0) {
            x /= base;
        }

        do {
            digit = (uint8_t) (uval / x);
            ADD_CHAR(digits[digit]);
            uval -= digit * x;
            x /= base;
        } while (x && (pos < len));
    }

    if (pos < len) str[pos] = 0;
    return pos;
#undef ADD_CHAR
}
Beispiel #4
0
static char *next_token(void) {
  static char *buffer = NULL;
  static int buffer_size = 0;
  int i, c;
  char *s;

  c = 0;
  for (s = pattern; *s; s++)
    ADD_CHAR(*s);

  for (i = 0; i < pattern_len; i++) {
    if (pattern[i] == '1') {
      ADD_CHAR(' ');
      for (s = words[cur_word + i]; *s; s++)
	ADD_CHAR(*s);
    }
  }
  ADD_CHAR('\0');
  cur_word++;
  return buffer;
}
Beispiel #5
0
bool RF12Module::SaveConfig() {
	// Variables used by the macros...
	byte pos, len;
	int remainder;
	memset(msg, 0, sizeof msg);
	strcpy(msg, " ");

	byte id = nodeId & 0x1F;
	strcat(msg, " i");
	ADD_INT(msg, id);
	if (nodeId & COLLECT)
		ADD_CHAR(msg, '*');

	strcat(msg, " g");
	ADD_INT(msg, group);

	strcat(msg, " @ ");
	static word bands[4] = { 315, 433, 868, 915 };
	word band = nodeId >> 6;
	ADD_INT(msg, bands[band]);
	strcat(msg, " MHz ");

	crc = ~0;
	for (byte i = 0; i < sizeof(*this) - 2; ++i)
		crc = _crc16_update(crc, ((byte*) this)[i]);

	// save to EEPROM
	for (byte i = 0; i < sizeof(*this); ++i) {
		byte b = ((byte*) this)[i];
		eeprom_write_byte(RF12_EEPROM_ADDR + i, b);
	}
	if (!rf12_config()) {
		Serial.print(RF12_EEPROM_SIZE);
		Serial.print( " vs ");
		Serial.println(sizeof(*this));
		return false;
	}
	return true;
}
static Bool
GetInputLine(FILE *file,InputLine *line,Bool checkbang)
{
int	ch;
Bool	endOfFile,spacePending,slashPending,inComment;

     endOfFile= FALSE;
     while ((!endOfFile)&&(line->num_line==0)) {
	spacePending= slashPending= inComment= FALSE;
	while (((ch=getc(file))!='\n')&&(ch!=EOF)) {
	    if (ch=='\\') {
		if ((ch=getc(file))==EOF)
		    break;
		if (ch=='\n') {
		    inComment= FALSE;
		    ch= ' ';
		    line->line_num++;
		}
	    }
	    if (inComment)
		continue;
	    if (ch=='/') {
		if (slashPending) {
		    inComment= TRUE;
		    slashPending= FALSE;
		}
		else {
		    slashPending= TRUE;
		}
		continue;
	    }
	    else if (slashPending) {
		if (spacePending) {
		    ADD_CHAR(line,' ');
		    spacePending= FALSE;
		}
		ADD_CHAR(line,'/');
		slashPending= FALSE;
	    }
	    if (isspace(ch)) {
		while (isspace(ch)&&(ch!='\n')&&(ch!=EOF)) {
		    ch= getc(file);
		}
		if (ch==EOF)
		    break;
		if ((ch!='\n')&&(line->num_line>0))
		    spacePending= TRUE;
		ungetc(ch,file);
	    }
	    else {
		if (spacePending) {
		    ADD_CHAR(line,' ');
		    spacePending= FALSE;
		}
		if (checkbang && ch=='!') {
		    if (line->num_line!=0) {
			DebugF("The '!' legal only at start of line\n");
			DebugF("Line containing '!' ignored\n");
			line->num_line= 0;
			inComment= 0;
			break;
		    }

		}
		ADD_CHAR(line,ch);
	    }
	}
	if (ch==EOF)
	     endOfFile= TRUE;
/*	else line->num_line++;*/
     }
     if ((line->num_line==0)&&(endOfFile))
	return FALSE;
      ADD_CHAR(line,'\0');
      return TRUE;
}
int CMakeSip::makeReq(int id, PHONE_CFG * cfg, ADDR *addrExt,STR_64 *str64ExtADDR)
{
   unsigned int iMeth=0;
   unsigned int uiFromLoc=0;
   unsigned int uiFromLen=0;
   strDstAddr.s=(unsigned char *)&spSes->dstSipAddr.strVal;
   strDstAddr.len=(int)spSes->dstSipAddr.uiLen;
   
   
   if(cfg){
      
      if(strcmp(&cfg->szSipTransport[0],"TLS")==0){iIsTCP=0;iIsTLS=1;}
      else if(strcmp(&cfg->szSipTransport[0],"TCP")==0){iIsTCP=1;iIsTLS=0;}
      else if(strcmp(&cfg->szSipTransport[0],"UDP")==0){iIsTCP=0;iIsTLS=0;}
      else {iIsTCP=0;iIsTLS=0;}
      
   }
   
   char *s=buf;
   
   int iPrevId=spSes->cs.iSendS;
   spSes->cs.iSendS=id;
   if(id!=METHOD_ACK)
   {
      if(iPrevId!=spSes->cs.iSendS)
      {
         if(spSes->cs.iSendS==METHOD_OPTIONS){
            spSes->sSendTo.setRetransmit(2,5*T_GT_SECOND);
         }
         else if(iIsTCP || iIsTLS)
            spSes->sSendTo.setRetransmit(7,5*T_GT_SECOND);
         else if(spSes->cs.iSendS==METHOD_REGISTER)
            spSes->sSendTo.setRetransmit(7,1*T_GT_SECOND);
         else  if(spSes->cs.iSendS==METHOD_INVITE)
            spSes->sSendTo.setRetransmit(7,(cfg==NULL || cfg->iNetworkIsMobile)?(6*T_GT_SECOND):(3*T_GT_SECOND));
         else
            spSes->sSendTo.setRetransmit();
      }
      spSes->cs.iWaitS=200;
   }
   else
   {
      spSes->cs.iWaitS=0;
   }
   
   //TODO getITFromZZ
   unsigned int uiCSeq;
#if 1
   if(cfg && id==METHOD_REGISTER)
   {
      if(!cfg->uiSipCSeq){
         //next reg should be with greater CSeq, even app restarts, if call-id is same
         //problem was with SIP Thor on OpenSIPS XS 1.4.5, but not  with FreeSwitch
         
         int get_time();
         cfg->uiSipCSeq=(unsigned int)get_time();
         cfg->uiSipCSeq-=1000000000;
      }
      cfg->uiSipCSeq++;
      uiCSeq=(unsigned int)cfg->uiSipCSeq;
   }
   else if(spSes){
      if(id!=METHOD_ACK && id!=METHOD_CANCEL)spSes->uiSipCseq++;
      uiCSeq=spSes->uiSipCseq;
   }
   else {
      uiCSeq=getTickCount();
      while(uiCSeq>1000000000)uiCSeq-=1000000000;
   }
#else
   static unsigned int  ss=User::TickCount();
   ss++;
   uiCSeq=ss;
   
#endif
   if(!uiCSeq)uiCSeq=1;

   int iReplaceRoute=0;
   
   if(iContactId >(int)sMsg->hldContact.uiCount)
      iContactId=0;

   GET_METH(id,iMeth);
   
   //TODO do we need to send route with cancel msg
#define METHOD_CANCEL_IGNORE 0
   
   struct HOLDER_CONTACT *hc = &sMsg->hldContact;
   HLD_ROUTE *hrr = &sMsg->hldRecRoute;
   
   //do i need to check "&& spSes->sSIPMsg.hldRecRoute.uiCount"?
   if(hc->uiCount<1 && spSes && spSes->sSIPMsg.hldContact.uiCount && sMsg->sipHdr.dstrStatusCode.uiVal>=300){
      hc = &spSes->sSIPMsg.hldContact;
      hrr = &spSes->sSIPMsg.hldRecRoute;
   }
   
   
   if(hc->x[iContactId].sipUri.dstrSipAddr.uiLen && (id & (METHOD_CANCEL_IGNORE|METHOD_REGISTER))==0)
   {
      if(hrr->uiCount)//TODO caller calle
      {
         iReplaceRoute=!hasRouteLR(hrr,0);
      }
      if(iReplaceRoute)
      {
         strDstAddr.s=(unsigned char *)hrr->x[0].sipUri.dstrSipAddr.strVal;
         strDstAddr.len=(int)hrr->x[0].sipUri.dstrSipAddr.uiLen;
      }
      else
      {
         strDstAddr.s=(unsigned char *)hc->x[iContactId].sipUri.dstrSipAddr.strVal;
         strDstAddr.len=(int)hc->x[iContactId].sipUri.dstrSipAddr.uiLen;
      }
   }
   //HDR
   ADD_DSTR(s,uiLen,sip_meth[iMeth]); ADD_CHAR(s,uiLen,' ');
   ADD_L_STR(s,uiLen,strDstAddr.s, strDstAddr.len);ADD_0_STR(s,uiLen," SIP/2.0\r\n");
   
   switch(id)
   {
      case METHOD_INVITE:
         sMsg->hdrCSeq.dstrID.uiVal=uiCSeq;
         break;
      case METHOD_ACK:
      case METHOD_CANCEL:
         uiCSeq=sMsg->hdrCSeq.dstrID.uiVal;
         break;
         
      case METHOD_REFER:
         //  ADD_STR(s,uiLen,"Refer-To: <");
         //ADD_DSTR(s,uiLen,spSes->str32Forward);
         //ADD_0_STR(s,uiLen,">\r\n");
         break;
         
      case METHOD_REGISTER:
         if(sMsg->hdrCSeq.dstrID.uiVal)uiCSeq=sMsg->hdrCSeq.dstrID.uiVal+1;//ast
         sMsg->hdrCSeq.dstrID.uiVal=uiCSeq;
      case METHOD_OPTIONS:
         
         ADD_STR(s,uiLen,"Allow: INVITE,ACK,CANCEL,OPTIONS,MESSAGE,BYE,INFO\r\n");
         if(id==METHOD_OPTIONS)
         {
            ADD_STR(s,uiLen,"Accept: application/sdp, text/plain\r\n");
         }
         break;
         
   }
   //TODO test asterisk add
   if((id & METHOD_REGISTER) && cfg && !cfg->reg.bUnReg && cfg->iUseOnlyNatIp==0 && sMsg &&  sMsg->hldVia.x[0].dstrRecived.uiLen<32)
   {
      if(sMsg->hldVia.x[0].dstrRecived.strVal && sMsg->hldVia.x[0].dstrRecived.uiLen){
         //TODO hi addr
         
         if(str64ExtADDR)
            spSes->pIPVisble=str64ExtADDR;
         
         memcpy(spSes->pIPVisble->strVal
                ,sMsg->hldVia.x[0].dstrRecived.strVal
                ,sMsg->hldVia.x[0].dstrRecived.uiLen);
         
         spSes->pIPVisble->uiLen=sMsg->hldVia.x[0].dstrRecived.uiLen;
         
         if(sMsg->hldVia.x[0].dstrRPort.uiVal)
            spSes->uiUserVisibleSipPort=sMsg->hldVia.x[0].dstrRPort.uiVal;
         
         if(addrExt)
         {
            addrExt->ip=ipstr2long(sMsg->hldVia.x[0].dstrRecived.uiLen,sMsg->hldVia.x[0].dstrRecived.strVal);
            
            SWAP_INT(addrExt->ip);
            addrExt->setPort((unsigned int)spSes->uiUserVisibleSipPort);
            
            
         }
      }
      else if(sMsg->hldVia.x[0].dstrRPort.uiVal){
         //  printf("[reg rport=%d ]",sMsg->hldVia.x[0].dstrRPort.uiVal);
         spSes->uiUserVisibleSipPort=sMsg->hldVia.x[0].dstrRPort.uiVal;
         addrExt->setPort((unsigned int)spSes->uiUserVisibleSipPort);
      }
   }
   
   if(iIsTCP)ADD_STR(s,uiLen,"Via: SIP/2.0/TCP ")
      else if(iIsTLS)ADD_STR(s,uiLen,"Via: SIP/2.0/TLS ")
         else ADD_STR(s,uiLen,"Via: SIP/2.0/UDP ")
            ADD_DSTR(s,uiLen,(*spSes->pIPVisble));
   
   if(spSes->uiUserVisibleSipPort!=DEAFULT_SIP_PORT)
      uiLen += sprintf(s + uiLen, ":%u", spSes->uiUserVisibleSipPort);
   
   ADD_STR(s,uiLen,";rport");
   ADD_STR(s,uiLen,";branch=z9hG4bK");
   ADD_L_STR(s,uiLen,sMsg->dstrCallID.strVal,4);
   if(id!=METHOD_CANCEL)
   {
      ADD_L_STR(s,uiLen,s,2);
   }
   else
   {
      ADD_STR(s,uiLen,"IN");
   }
   
   uiLen += sprintf(s + uiLen, "%u",uiCSeq^0x123);
   
   
   
   
   ADD_CRLF(s,uiLen);
   
   uiLen += sprintf(s + uiLen, "CSeq: %u ", uiCSeq);
   ADD_DSTRCRLF(s,uiLen,sip_meth[iMeth])
   
   
   
   if((id & (METHOD_REGISTER|METHOD_CANCEL))
      || (spSes->cs.iCaller  && (sMsg==NULL || sMsg->hdrCSeq.uiMethodID==0)))
   {
      
      ADD_FSTR(s,uiLen,"From: ",6);
      {
         uiFromLoc=uiLen;
         if(cfg->user.nick[0]){
            ADD_CHAR(s,uiLen,'"');
            ADD_0_STR(s,uiLen,cfg->user.nick);
            ADD_CHAR(s,uiLen,'"');
         }
         uiLen+=sprintf(s+uiLen," <%.*s>",D_STR(spSes->userSipAddr));
         
         uiFromLen=uiLen-uiFromLoc;
         
         if(spSes->str16Tag.uiLen)
         {
            ADD_0_STR(s,uiLen,";tag=");
            ADD_DSTRCRLF(s,uiLen,spSes->str16Tag);
         }
         else ADD_CRLF(s,uiLen);
         
      }
      {
         
         if((sMsg->hdrTo.dstrTag.uiLen==0 && id!=METHOD_REGISTER)
            || (id & METHOD_CANCEL)
            )
         {
            //  puts("a4");
            ADD_FSTR(s,uiLen,"To: <",5);
            //vajag lai straadaatu 3xx vispaar sho laikam jau nevajag,
            //jo es jau iedoshu liidzi sMsg kuru saneemu
            if(spSes && spSes->sSIPMsg.hdrTo.sipUri.dstrSipAddr.uiLen==0)
            {
               spSes->sSIPMsg.hdrTo.sipUri.dstrSipAddr.strVal=
               (char *)&spSes->sSIPMsg.rawDataBuffer+spSes->sSIPMsg.uiOffset;
               ADD_DSTR((char *)&spSes->sSIPMsg.rawDataBuffer, spSes->sSIPMsg.uiOffset,spSes->dstSipAddr);
               
               spSes->sSIPMsg.hdrTo.sipUri.dstrSipAddr.uiLen=spSes->dstSipAddr.uiLen;
               //varbuut sho saglabaat pie get new ses
            }
            if(sMsg->hdrTo.sipUri.dstrSipAddr.strVal)
            {
               ADD_DSTR(s,uiLen,sMsg->hdrTo.sipUri.dstrSipAddr);
            }
            else
            {
               ADD_DSTR(s,uiLen,spSes->dstSipAddr);
            }
            ADD_FSTR(s,uiLen,">\r\n",3);
            
            // puts("a5");
         }
         else if (id==METHOD_REGISTER)
         {
            //  DEBUG(0,"make register---------")
            ADD_FSTR(s,uiLen,"To: ",4);
            memcpy(s+uiLen,s+uiFromLoc,uiFromLen);
            uiLen+=uiFromLen;
            ADD_CRLF(s,uiLen);
         }
         else
         {
            ADD_DSTRCRLF(s,uiLen,sMsg->hdrTo.dstrFullRow);
            //  puts("a6");
         }
      }
   }
   else
   {
      //TODO use full row
      //      char *pMeth1;
      //    char *pMeth2;
      DSTR *fromAddr;
      DSTR *toAddr;
      DSTR *tag;
      //   puts("a7");
      
      if(sMsg->sipHdr.dstrStatusCode.uiVal)
      {
         fromAddr=&sMsg->hdrFrom.sipUri.dstrSipAddr;
         toAddr=&sMsg->hdrTo.sipUri.dstrSipAddr;
         tag=&sMsg->hdrTo.dstrTag;
         //    puts("a8");
      }
      else
      {
         toAddr=&sMsg->hdrFrom.sipUri.dstrSipAddr;
         fromAddr=&sMsg->hdrTo.sipUri.dstrSipAddr;
         tag=&sMsg->hdrFrom.dstrTag;
         //  puts("a9");
      }
      
      uiLen+=sprintf(s+uiLen,"From: <%.*s>", D_STR(*fromAddr));
      if(spSes->str16Tag.uiLen)
      {
         ADD_0_STR(s,uiLen,";tag=");
         ADD_DSTRCRLF(s,uiLen,spSes->str16Tag);
      }
      else ADD_CRLF(s,uiLen);
      

      uiLen+=sprintf(s+uiLen,"To: <%.*s>", D_STR(*toAddr));
      
      if(tag->uiLen && !fToTagIgnore)
      {
         ADD_0_STR(s,uiLen,";tag=");
         ADD_DSTRCRLF(s,uiLen,(*tag));
      }
      else ADD_CRLF(s,uiLen);
   }
   
   ADD_FSTR(s,uiLen,"Call-ID: ",9);
   ADD_DSTRCRLF(s,uiLen,sMsg->dstrCallID);
   ADD_STR(s,uiLen,"Max-Forwards: 70\r\n");
   
   if(id==METHOD_REGISTER){
      if(cfg && cfg->szUA[0]){
         ADD_STR(s,uiLen,"User-Agent: ");
         ADD_0_STR(s,uiLen,cfg->szUA);ADD_CRLF(s,uiLen);
      }
      else{
         ADD_STR(s,uiLen,USER_AGENT);
      }
   }
   
   
   if(id != METHOD_CANCEL_IGNORE && (hrr->uiCount || iReplaceRoute))//(toMake & (METHOD_BYE |METHOD_ACK)) && ???
   {
      
      uiLen+=addRoute(s+uiLen, 255, hrr, "Route: ",
                      !((sMsg->hdrCSeq.uiMethodID && sMsg->sipHdr.dstrStatusCode.uiVal) ||
                        (spSes->cs.iCaller && sMsg->hdrCSeq.uiMethodID==0))
                      ,iReplaceRoute, &hc->x[iContactId].sipUri.dstrSipAddr);
      
   }
   
   if(id & (METHOD_INVITE | METHOD_OPTIONS |METHOD_MESSAGE |METHOD_REGISTER|METHOD_REFER|METHOD_SUBSCRIBE|METHOD_PUBLISH|METHOD_UPDATE))
   {
      //unsigned int uiPos;
      if(cfg && cfg->user.nick[0]){
         uiLen+=sprintf(s+uiLen,"Contact: \"%s\" <sip:",cfg->user.nick);//sUserCfg.szUserName);
      }
      else {ADD_STR(s,uiLen,"Contact: <sip:");}
      //uiPos=uiLen;
      
      //TODO if register store contact addr and use it until next reg
      
      if(cfg  && (cfg->isOnline() || (id & METHOD_REGISTER)))
      {
         if(*cfg->user.nr)
            uiLen+=sprintf(s+uiLen,"%s@",cfg->user.nr);
         else if(*cfg->user.un)
            uiLen+=sprintf(s+uiLen,"%s@",cfg->user.un);
      }
      
      ADD_DSTR(s,uiLen,(*spSes->pIPVisble));
      
      
      if(spSes->uiUserVisibleSipPort!=DEAFULT_SIP_PORT)
         uiLen+=sprintf(s+uiLen,":%u",spSes->uiUserVisibleSipPort);
      
      
      
      if(iIsTCP) {ADD_STR(s,uiLen,";transport=tcp>")}else
         if(iIsTLS) {ADD_STR(s,uiLen,";transport=tls>")} else
         { ADD_FSTR(s,uiLen,">",1)}
Beispiel #8
0
struct cfg_tokens* cfg_tokenize(const char* line)
{
	struct cfg_tokens* tokens = (struct cfg_tokens*) hub_malloc_zero(sizeof(struct cfg_tokens));
	char* buffer = (char*) hub_malloc_zero(strlen(line) + 1);
	char* out = buffer;
	const char* p = line;
	int backslash = 0;
	char quote = 0;
	size_t token_count = 0;
	size_t token_size = 0;
	tokens->list = list_create();

	for (; *p; p++)
	{
		switch (*p)
		{
			case '\\':
				if (backslash)
				{
					ADD_CHAR('\\');
					backslash = 0;
				}
				else
				{
					backslash = 1;
				}
				break;

			case '#':
				if (backslash)
				{
					ADD_CHAR('#');
					backslash = 0;
				}
				else if (quote)
				{
					ADD_CHAR('#');
				}
				else
				{
					RESET_TOKEN;
					hub_free(buffer);
					return tokens;
				}
				break;

			case '"':
				if (backslash)
				{
					ADD_CHAR('"');
					backslash = 0;
				}
				else if (quote)
				{
					quote = 0;
				}
				else
				{
					quote = 1;
				}
				break;

			case '\r':
				/* Pretend it does not exist! */
				break;

			case ' ':
			case '\t':
				if (quote)
				{
					ADD_CHAR(*p);
				}
				else if (backslash)
				{
					ADD_CHAR(*p);
					backslash = 0;
				}
				else
				{
					RESET_TOKEN;
				}
				break;

			default:
				ADD_CHAR(*p);
		}
	}

	RESET_TOKEN;
	hub_free(buffer);
	return tokens;
}
Beispiel #9
0
int parse_get_token (char *buf, int limit)
{
	int token_index = 0;
	int escape_state = FALSE;
	int quoted_state = FALSE;
	int comment_state = FALSE;
	int token_truncated = FALSE;

	char	current_ch, ch;

	do
	{
		current_ch = get_next_char();
		if (comment_state)
		{
			/*
				A comment is ended by an EOLN or EOF.
				If cont_line is not 0, we keep looking
				for a token (or until a EOF is hit).
				If it is, we return EOF or EOLN.
			*/
			if (current_ch == '\n')
			{
				if (cont_line == 0)
				{
					first_word = TRUE;
					return GW_EOLN;
				}
				comment_state = FALSE;
			}
			else if (current_ch == '\0')
			{
				first_word = TRUE;
				if (cont_line)
					return GW_ERRCONTINUATION;
				else
					return GW_EOF;
			}
		}
		else if (escape_state)
		{
			/*
				An escape character was hit.  The next
				character is copied in (re-escaped) with
				the exception of the end of line - which is
				copied unescaped.

				If a digit follows the escape character there
				are supposed to be two more, but that error
				checking is left to the next level of parsing.
			*/
			if (current_ch == '\n')
			{
				ADD_CHAR (buf, current_ch);
			}
			else if (current_ch == 0x7F || current_ch < 0x20)
			{
				do
					ch = get_next_char();
				while (ch != '\n' && ch != '\0');
				if (ch== '\0') put_back_char (ch);

				first_word = TRUE;
				cont_line = 0;
				return GW_ERRILLEGALCHAR;
			}
			else
			{
				ADD_CHAR (buf, '\\');
				ADD_CHAR (buf, current_ch);
			}
			escape_state = FALSE;
		}
		else if (quoted_state)
		{
			/*
				In the middle of a quote, escapes matter,
				and we don't return the enclosing quote
				marks.
			*/
			if (current_ch == '\\')
				escape_state = TRUE;
			else if (current_ch == '\n' || current_ch == '\0')
			{
				buf[token_index]='\0';
				if (cont_line > 0)
				{
					while (cont_line > 0)
					{
						do
							ch = get_next_char();
						while (ch != '\n' && ch != '\0');
						cont_line--;
					}
					put_back_char (ch);
				}
				first_word = TRUE;
				cont_line = 0;
				return GW_ERRDANGLINGQUOTE;
			}
			else if (current_ch == '"')
			{
				buf[token_index]='\0';
				return GW_MAYBE_WORD;
			}
			else if (current_ch!='\t' && (current_ch<0x20 || current_ch==0x7F))
			{
				do
					ch = get_next_char();
				while (ch != '\n' && ch != '\0');

				first_word = TRUE;
				cont_line = 0;
				return GW_ERRILLEGALCHAR;
			}
			else
			{
				ADD_CHAR (buf, current_ch);
			}
		}
		else if (token_index > 0)
		{
			/*
				In this case, there is a token being
				built.  It is either added to or a
				separating character ends it and itself
				may be left (e.g., a ; beginning a comment
				ends the previous token and is left to
				signal the start of the comment next time
				around.
			*/
			if (isspace(current_ch)&&current_ch!='\n'&&current_ch!='\0')
			{
				first_word = FALSE;
				buf[token_index]='\0';
				if (current_ch== '\0') put_back_char (current_ch);
				return GW_MAYBE_WORD;
			}
			else if (current_ch == '\\')
			{
				escape_state = TRUE;
			}
			else if (SEPARATOR(current_ch))
			{
				first_word = FALSE;
				put_back_char (current_ch);
				buf[token_index]='\0';
				return GW_MAYBE_WORD;
			}
			else if (current_ch < 0x20 || current_ch == 0x7F)
			{
				do
					ch = get_next_char();
				while (ch != '\n' && ch != '\0');
				if (ch== '\0') put_back_char (ch);

				first_word = TRUE;
				cont_line = 0;
				return GW_ERRILLEGALCHAR;
			}
			else
				ADD_CHAR (buf, current_ch);
		}
		else
			/*
				The character is potentially the
				start of a token.  Some of these
				may have been seen by the above code and
				returned to the input stream.
			*/
			switch (current_ch)
			{
				case ';':
					buf[token_index]='\0';
					comment_state = TRUE;
					break;
				case '(':
					cont_line++;
					do
						ch = get_next_char();
					while (ch != '\n' && ch != '\0');
					if (ch== '\0') put_back_char (ch);

					first_word = FALSE;
					break;
				case ')':
					cont_line--;
					while ((ch = get_next_char()) != '\n')
					{
						if (ch == '\0') return GW_EOF;
						if (ch == ')')
						{
							put_back_char (ch);
							break;
						}
					}
					if (cont_line==0)
					{
						first_word = TRUE;
						return GW_EOLN;
					}
					if (cont_line < 0)
					{
						/*
							We've already read to
							the end of the line
						*/
						first_word = TRUE;
						cont_line = 0;
						return GW_ERRCONTINUATION;
					}
					break;
				case ' ': case '\t':
					if (first_word)
					{
						ADD_CHAR (buf, current_ch);
						buf[token_index]='\0';
						first_word = FALSE;
						return GW_MAYBE_WORD;
					}
					break;
				case '\\':
					escape_state = TRUE;
					break;
				case '"':
					quoted_state = TRUE;
					break;
				case '\n':
					if (cont_line==0)
					{
						first_word = TRUE;
						return GW_EOLN;
					}
					break;
				case '\0':
					if (cont_line == 0)
						return GW_EOF;
					else
					{
						cont_line = 0;
						return GW_ERRCONTINUATION;
					}
				default:
					if (current_ch<0x20 || current_ch==0x7F)
					{
						do
							ch = get_next_char();
						while (ch != '\n' && ch != '\0');
						if (ch== '\0') put_back_char (ch);

						first_word = TRUE;
						cont_line = 0;
						return GW_ERRILLEGALCHAR;
					}
					else
					{
						ADD_CHAR (buf, current_ch);
					}
			} /* end switch body */
	} while (TRUE); /* end the do-while loop */
}
Beispiel #10
0
/*
 * THE (s)printf() function.
 * It returns a pointer to it's internal buffer (or a string in the text
 * segment) thus, the string must be copied if it has to survive after
 * this function is called again, or if it's going to be modified (esp.
 * if it risks being free()ed).
 */
char *string_print_formatted (const char * format_str, int argc, svalue_t * argv)
{
    format_info finfo;
    svalue_t *carg;     /* current arg */
    unsigned int nelemno = 0;   /* next offset into array */
    unsigned int fpos;          /* position in format_str */
    int fs;                     /* field size */
    int pres;                   /* precision */
    pad_info_t pad;             /* fs pad string */
    unsigned int i;
    char *retvalue;
    int last;

    push_sprintf_state();
    STACK_INC;
    sp->type = T_ERROR_HANDLER;
    sp->u.error_handler = pop_sprintf_state;

    last = 0;
    for (fpos = 0; 1; fpos++) {
        char c = format_str[fpos];

        if (c == '\n' || !c) {
            int column_stat = 0;

            if (last != fpos) {
                add_nstr(format_str + last, fpos - last);
                last = fpos + 1;
            } else last++;

            if (!sprintf_state->csts) {
                if (!c)
                    break;
                ADD_CHAR('\n');
                continue;
            }
            ADD_CHAR('\n');
            while (sprintf_state->csts) {
                cst **temp;

                temp = &(sprintf_state->csts);
                while (*temp) {
                    if ((*temp)->info & INFO_COLS) {
                        if (*((*temp)->d.col - 1) != '\n')
                            while (*((*temp)->d.col) == ' ')
                                (*temp)->d.col++;
                        add_pad(0, (*temp)->start - get_curpos());
                        column_stat = add_column(temp, 0);
                        if (!column_stat)
                            temp = &((*temp)->next);
                    } else {
                        add_pad(0, (*temp)->start - get_curpos());
                        if (!add_table(temp))
                            temp = &((*temp)->next);
                    }
                }               /* of while (*temp) */
                if (sprintf_state->csts || c == '\n')
                    ADD_CHAR('\n');
            }                   /* of while (sprintf_state->csts) */
            if (column_stat == 2)
                ADD_CHAR('\n');
            if (!c)
                break;
        } else
            if (c == '%') {
                if (last != fpos) {
                    add_nstr(format_str + last, fpos - last);
                    last = fpos + 1;
                } else last++;
                if (format_str[fpos + 1] == '%') {
                    ADD_CHAR('%');
                    fpos++;
                    last++;
                    continue;
                }
                GET_NEXT_ARG;
                fs = 0;
                pres = 0;
                pad.len = 0;
                finfo = 0;
                for (fpos++; !(finfo & INFO_T); fpos++) {
                    if (!format_str[fpos]) {
                        finfo |= INFO_T_ERROR;
                        break;
                    }
                    if (((format_str[fpos] >= '0') && (format_str[fpos] <= '9'))
                            || (format_str[fpos] == '*')) {
                        if (pres == -1) {   /* then looking for pres */
                            if (format_str[fpos] == '*') {
                                if (carg->type != T_NUMBER)
                                    ERROR(ERR_INVALID_STAR);
                                pres = carg->u.number;
                                GET_NEXT_ARG;
                                continue;
                            }
                            pres = format_str[fpos] - '0';
                            for (fpos++;
                                    (format_str[fpos] >= '0') && (format_str[fpos] <= '9'); fpos++) {
                                pres = pres * 10 + format_str[fpos] - '0';
                            }
                            if (pres < 0) pres = 0;
                        } else {    /* then is fs (and maybe pres) */
                            if ((format_str[fpos] == '0') && (((format_str[fpos + 1] >= '1')
                                            && (format_str[fpos + 1] <= '9')) || (format_str[fpos + 1] == '*'))) {
                                pad.what = "0";
                                pad.len = 1;
                            } else {
                                if (format_str[fpos] == '*') {
                                    if (carg->type != T_NUMBER)
                                        ERROR(ERR_INVALID_STAR);
                                    fs = carg->u.number;
                                    if (fs < 0) fs = 0;
                                    if (pres == -2)
                                        pres = fs;  /* colon */
                                    GET_NEXT_ARG;
                                    continue;
                                }
                                fs = format_str[fpos] - '0';
                            }
                            for (fpos++;
                                    (format_str[fpos] >= '0') && (format_str[fpos] <= '9'); fpos++) {
                                fs = fs * 10 + format_str[fpos] - '0';
                            }
                            if (fs < 0) fs = 0;
                            if (pres == -2) {       /* colon */
                                pres = fs;
                            }
                        }
                        fpos--; /* about to get incremented */
                        continue;
                    }
                    switch (format_str[fpos]) {
                        case ' ':
                            finfo |= INFO_PP_SPACE;
                            break;
                        case '+':
                            finfo |= INFO_PP_PLUS;
                            break;
                        case '-':
                            finfo |= INFO_J_LEFT;
                            break;
                        case '|':
                            finfo |= INFO_J_CENTRE;
                            break;
                        case '@':
                            finfo |= INFO_ARRAY;
                            break;
                        case '=':
                            finfo |= INFO_COLS;
                            break;
                        case '#':
                            finfo |= INFO_TABLE;
                            break;
                        case '.':
                            pres = -1;
                            break;
                        case ':':
                            pres = -2;
                            break;
#ifdef DEBUG
                        case '%':
                            finfo |= INFO_T_NULL;
                            break;      /* never reached */
#endif
                        case 'O':
                            finfo |= INFO_T_LPC;
                            break;
                        case 's':
                            finfo |= INFO_T_STRING;
                            break;
                        case 'd':
                        case 'i':
                            finfo |= INFO_T_INT;
                            break;
                        case 'f':
                            finfo |= INFO_T_FLOAT;
                            break;
                        case 'c':
                            finfo |= INFO_T_CHAR;
                            break;
                        case 'o':
                            finfo |= INFO_T_OCT;
                            break;
                        case 'x':
                            finfo |= INFO_T_HEX;
                            break;
                        case 'X':
                            finfo |= INFO_T_C_HEX;
                            break;
                        case '\'':
                            fpos++;
                            pad.what = format_str + fpos;
                            while (1) {
                                if (!format_str[fpos])
                                    ERROR(ERR_UNEXPECTED_EOS);
                                if (format_str[fpos] == '\\') {
                                    if (!format_str[++fpos])
                                        ERROR(ERR_UNEXPECTED_EOS);
                                } else
                                    if (format_str[fpos] == '\'') {
                                        pad.len = format_str + fpos - pad.what;
                                        if (!pad.len)
                                            ERROR(ERR_NULL_PS);
                                        break;
                                    }
                                fpos++;
                            }
                            break;
                        default:
                            finfo |= INFO_T_ERROR;
                    }
                }                   /* end of for () */
                if (pres < 0)
                    ERROR(ERR_PRES_EXPECTED);
                /*
                 * now handle the different arg types...
                 */
                if (finfo & INFO_ARRAY) {
                    if (carg->type != T_ARRAY)
                        ERROR(ERR_ARRAY_EXPECTED);
                    if (carg->u.arr->size == 0) {
                        last = fpos;
                        fpos--;     /* 'bout to get incremented */
                        continue;
                    }
                    carg = (argv + sprintf_state->cur_arg)->u.arr->item;
                    nelemno = 1;    /* next element number */
                }
                while (1) {
                    if ((finfo & INFO_T) == INFO_T_LPC) {
                        outbuffer_t outbuf;

                        outbuf_zero(&outbuf);
                        svalue_to_string(carg, &outbuf, 0, 0, 0);
                        outbuf_fix(&outbuf);

                        sprintf_state->clean.type = T_STRING;
                        sprintf_state->clean.subtype = STRING_MALLOC;
                        sprintf_state->clean.u.string = outbuf.buffer;
                        carg = &(sprintf_state->clean);
                        finfo ^= INFO_T_LPC;
                        finfo |= INFO_T_STRING;
                    }
                    if ((finfo & INFO_T) == INFO_T_ERROR) {
                        ERROR(ERR_INVALID_FORMAT_STR);
#ifdef DEBUG
                    } else if ((finfo & INFO_T) == INFO_T_NULL) {
                        /* never reached... */
                        fprintf(stderr, "/%s: (s)printf: INFO_T_NULL.... found.\n",
                                current_object->obname);
                        ADD_CHAR('%');
#endif
                    } else if ((finfo & INFO_T) == INFO_T_STRING) {
                        int slen;
                        /*
                         * %s null handling added 930709 by Luke Mewburn
                         * <*****@*****.**>
                         */
                        if (carg->type == T_NUMBER && carg->u.number == 0) {
                            sprintf_state->clean.type = T_STRING;
                            sprintf_state->clean.subtype = STRING_MALLOC;
                            sprintf_state->clean.u.string = string_copy(NULL_MSG, "sprintf NULL");
                            carg = &(sprintf_state->clean);
                        } else
                            if (carg->type != T_STRING) {
                                ERROR(ERR_INCORRECT_ARG_S);
                            }
                        slen = SVALUE_STRLEN(carg);
                        if ((finfo & INFO_COLS) || (finfo & INFO_TABLE)) {
                            cst **temp;

                            if (!fs) {
                                ERROR(ERR_CST_REQUIRES_FS);
                            }

                            temp = &(sprintf_state->csts);
                            while (*temp)
                                temp = &((*temp)->next);
                            if (finfo & INFO_COLS) {
                                int tmp;
                                if (pres > fs) pres = fs;
                                *temp = ALLOCATE(cst, TAG_TEMPORARY, "string_print: 3");
                                (*temp)->next = 0;
                                (*temp)->d.col = carg->u.string;
                                (*temp)->pad = make_pad(&pad);
                                (*temp)->size = fs;
                                (*temp)->pres = (pres) ? pres : fs;
                                (*temp)->info = finfo;
                                (*temp)->start = get_curpos();
#ifdef TCC
                                puts("tcc has some bugs");
#endif
                                tmp = ((format_str[fpos] != '\n')
                                        && (format_str[fpos] != '\0'))
                                    || ((finfo & INFO_ARRAY)
                                            && (nelemno < (argv + sprintf_state->cur_arg)->u.arr->size));
                                tmp = add_column(temp, tmp);
                                if (tmp == 2 && !format_str[fpos]) {
                                    ADD_CHAR('\n');
                                }
                            } else {/* (finfo & INFO_TABLE) */
                                unsigned int n, len, max_len;
                                const char *p1, *p2;

#define TABLE carg->u.string
                                (*temp) = ALLOCATE(cst, TAG_TEMPORARY, "string_print: 4");
                                (*temp)->d.tab = 0;
                                (*temp)->pad = make_pad(&pad);
                                (*temp)->info = finfo;
                                (*temp)->start = get_curpos();
                                (*temp)->next = 0;
                                max_len = 0;
                                n = 1;

                                p2 = p1 = TABLE;
                                while (*p1) {
                                    if (*p1 == '\n') {
                                        if (p1 - p2 > max_len)
                                            max_len = p1 - p2;
                                        p1++;
                                        if (*(p2 = p1))
                                            n++;
                                    } else
                                        p1++;
                                }
                                if (!pres) {
                                    /* the null terminated word */
                                    if (p1 - p2 > max_len)
                                        max_len = p1 - p2;
                                    pres = fs / (max_len + 2); /* at least two
                                                                * separating spaces */
                                    if (!pres)
                                        pres = 1;

                                    /* This moves some entries from the right side
                                     * of the table to fill out the last line,
                                     * which makes the table look a bit nicer.
                                     * E.g.
                                     * (n=13,p=6)      (l=3,p=5)
                                     * X X X X X X     X X X X X
                                     * X X X X X X  -> X X X X X
                                     * X               X X X X
                                     *
                                     */
                                    len = (n-1)/pres + 1;
                                    if (n > pres && n % pres)
                                        pres -= (pres - n % pres) / len;
                                } else {
                                    len = (n-1)/pres + 1;
                                }
                                (*temp)->size = fs / pres;
                                (*temp)->remainder = fs % pres;
                                if (n < pres) {
                                    /* If we have fewer elements than columns,
                                     * pretend we are dealing with a smaller
                                     * table.
                                     */
                                    (*temp)->remainder += (pres - n)*((*temp)->size);
                                    pres = n;
                                }

                                (*temp)->d.tab = CALLOCATE(pres + 1, tab_data_t,
                                        TAG_TEMPORARY, "string_print: 5");
                                (*temp)->nocols = pres;     /* heavy sigh */
                                (*temp)->d.tab[0].start = TABLE;
                                if (pres == 1) {
                                    (*temp)->d.tab[1].start = TABLE + SVALUE_STRLEN(carg) + 1;
                                } else {
                                    i = 1;  /* the next column number */
                                    n = 0;  /* the current "word" number in this
                                             * column */

                                    p1 = TABLE;
                                    while (*p1) {
                                        if (*p1++ == '\n' && ++n >= len) {
                                            (*temp)->d.tab[i++].start = p1;
                                            n = 0;
                                        }
                                    }
                                    for ( ; i <= pres; i++)
                                        (*temp)->d.tab[i].start = ++p1;
                                }
                                for (i = 0; i < pres; i++)
                                    (*temp)->d.tab[i].cur = (*temp)->d.tab[i].start;

                                add_table(temp);
                            }
                        } else {    /* not column or table */
                            const char *tmp = carg->u.string; //work around tcc bug;
                            if (pres && pres < slen)
                                slen = pres;
                            add_justified(tmp, slen, &pad, fs, finfo,
                                    (((format_str[fpos] != '\n') && (format_str[fpos] != '\0'))
                                     || ((finfo & INFO_ARRAY) && (nelemno < (argv + sprintf_state->cur_arg)->u.arr->size)))
                                    || carg->u.string[slen - 1] != '\n');
                        }
                    } else if (finfo & INFO_T_INT) {        /* one of the integer
                                                             * types */
                        char cheat[20];
                        char temp[100];

                        *cheat = '%';
                        i = 1;
                        switch (finfo & INFO_PP) {
                            case INFO_PP_SPACE:
                                cheat[i++] = ' ';
                                break;
                            case INFO_PP_PLUS:
                                cheat[i++] = '+';
                                break;
                        }
                        if (pres) {
                            cheat[i++] = '.';
                            if(pres >= sizeof(temp))
                                sprintf(cheat + i, "%ld", sizeof(temp) - 1);
                            else
                                sprintf(cheat + i, "%d", pres);

                            i += strlen(cheat + i);
                        }
                        switch (finfo & INFO_T) {
                            case INFO_T_INT:
                                cheat[i++] = 'l';
                                cheat[i++] = 'd';
                                break;
                            case INFO_T_FLOAT:
                                cheat[i++] = 'f';
                                break;
                            case INFO_T_CHAR:
                                cheat[i++] = 'c';
                                break;
                            case INFO_T_OCT:
                                cheat[i++] = 'l';
                                cheat[i++] = 'o';
                                break;
                            case INFO_T_HEX:
                                cheat[i++] = 'l';
                                cheat[i++] = 'x';
                                break;
                            case INFO_T_C_HEX:
                                cheat[i++] = 'l';
                                cheat[i++] = 'X';
                                break;
                            default:
                                ERROR(ERR_BAD_INT_TYPE);
                        }
                        if ((cheat[i - 1] == 'f' && carg->type != T_REAL) || (cheat[i - 1] != 'f' && carg->type != T_NUMBER)) {
#ifdef RETURN_ERROR_MESSAGES
                            sprintf(buff,
                                    "ERROR: (s)printf(): Incorrect argument type to %%%c. (arg: %u)\n",
                                    cheat[i - 1], sprintf_state->cur_arg);
                            fprintf(stderr, "Program /%s File: %s: %s", current_prog->name,
                                    get_line_number_if_any(), buff);
                            debug_message("%s", buff);
                            if (current_object) {
                                debug_message("program: /%s, object: %s, file: %s\n",
                                        current_prog ? current_prog->name : "",
                                        current_object->name,
                                        get_line_number_if_any());
                            }
                            ERROR(ERR_RECOVERY_ONLY);
#else
                            error("ERROR: (s)printf(): Incorrect argument type to %%%c.\n",
                                    cheat[i - 1]);
#endif                          /* RETURN_ERROR_MESSAGES */
                        }
                        cheat[i] = '\0';

                        if (carg->type == T_REAL) {
                            sprintf(temp, cheat, carg->u.real);
                        } else
                            sprintf(temp, cheat, carg->u.number);
                        {
                            int tmpl = strlen(temp);

                            add_justified(temp, tmpl, &pad, fs, finfo,
                                    (((format_str[fpos] != '\n') && (format_str[fpos] != '\0'))
                                     || ((finfo & INFO_ARRAY) && (nelemno < (argv + sprintf_state->cur_arg)->u.arr->size))));
                        }
                    } else          /* type not found */
                        ERROR(ERR_UNDEFINED_TYPE);
                    if (sprintf_state->clean.type != T_NUMBER) {
                        free_svalue(&(sprintf_state->clean), "string_print_formatted");
                        sprintf_state->clean.type = T_NUMBER;
                    }

                    if (!(finfo & INFO_ARRAY))
                        break;
                    if (nelemno >= (argv + sprintf_state->cur_arg)->u.arr->size)
                        break;
                    carg = (argv + sprintf_state->cur_arg)->u.arr->item + nelemno++;
                }                   /* end of while (1) */
                last = fpos;
                fpos--;             /* bout to get incremented */
            }
    }                           /* end of for (fpos=0; 1; fpos++) */

    outbuf_fix(&sprintf_state->obuff);
    retvalue = sprintf_state->obuff.buffer;
    sprintf_state->obuff.buffer = 0;
    pop_stack();                /* pop off our error handler, will call pop_sprintf_state */
    return retvalue;
}                               /* end of string_print_formatted() */
Beispiel #11
0
static void pcf_print_master_field(VSTREAM *fp, int mode,
				           PCF_MASTER_ENT *masterp,
				           int field)
{
    char  **argv = masterp->argv->argv;
    const char *arg;
    const char *aval;
    int     arg_len;
    int     line_len;
    int     in_daemon_options;
    int     need_parens;

    /*
     * Show the field value, or the first value in the case of a multi-column
     * field.
     */
#define ADD_CHAR(ch) ADD_TEXT((ch), 1)

    line_len = 0;
    if ((mode & PCF_HIDE_NAME) == 0) {
	ADD_TEXT(argv[0], strlen(argv[0]));
	ADD_CHAR(PCF_NAMESP_SEP_STR);
	ADD_TEXT(argv[1], strlen(argv[1]));
	ADD_CHAR(PCF_NAMESP_SEP_STR);
	ADD_TEXT(pcf_str_field_pattern(field), strlen(pcf_str_field_pattern(field)));
    }
    if ((mode & (PCF_HIDE_NAME | PCF_HIDE_VALUE)) == 0) {
	ADD_TEXT(" = ", 3);
    }
    if ((mode & PCF_HIDE_VALUE) == 0) {
	if (line_len > 0 && line_len + strlen(argv[field]) > PCF_LINE_LIMIT) {
	    vstream_fputs("\n" PCF_INDENT_TEXT, fp);
	    line_len = PCF_INDENT_LEN;
	}
	ADD_TEXT(argv[field], strlen(argv[field]));
    }

    /*
     * Format the daemon command-line options and non-option arguments. Here,
     * we have no data-dependent preference for column positions, but we do
     * have argument grouping preferences.
     */
    if (field == PCF_MASTER_FLD_CMD && (mode & PCF_HIDE_VALUE) == 0) {
	in_daemon_options = 1;
	for (field += 1; (arg = argv[field]) != 0; field++) {
	    arg_len = strlen(arg);
	    aval = 0;
	    need_parens = 0;
	    if (in_daemon_options) {

		/*
		 * We make no special case for generic options (-v -D)
		 * options.
		 */
		if (arg[0] != '-' || strcmp(arg, "--") == 0) {
		    in_daemon_options = 0;
		} else if (strchr(pcf_daemon_options_expecting_value, arg[1]) != 0
			   && (aval = argv[field + 1]) != 0) {

		    /* Force line break before option with value. */
		    line_len = PCF_LINE_LIMIT;

		    /*
		     * Optionally, expand $name in parameter value.
		     */
		    if (strcmp(arg, "-o") == 0
			&& (mode & PCF_SHOW_EVAL) != 0)
			aval = pcf_expand_parameter_value((VSTRING *) 0, mode,
							  aval, masterp);

		    /*
		     * Keep option and value on the same line.
		     */
		    arg_len += strlen(aval) + 1;
		    if ((need_parens = aval[strcspn(aval, PCF_MASTER_BLANKS)]) != 0)
			arg_len += 2;
		}
	    } else {
		need_parens = arg[strcspn(arg, PCF_MASTER_BLANKS)];
	    }

	    /*
	     * Insert a line break when the next item won't fit.
	     */
	    if (line_len > PCF_INDENT_LEN) {
		if ((mode & PCF_FOLD_LINE) == 0
		    || line_len + 1 + arg_len < PCF_LINE_LIMIT) {
		    ADD_SPACE;
		} else {
		    vstream_fputs("\n" PCF_INDENT_TEXT, fp);
		    line_len = PCF_INDENT_LEN;
		}
	    }
	    if (in_daemon_options == 0 && need_parens)
		ADD_TEXT("{", 1);
	    ADD_TEXT(arg, strlen(arg));
	    if (in_daemon_options == 0 && need_parens)
		ADD_TEXT("}", 1);
	    if (aval) {
		ADD_SPACE;
		if (need_parens)
		    ADD_TEXT("{", 1);
		ADD_TEXT(aval, strlen(aval));
		if (need_parens)
		    ADD_TEXT("}", 1);
		field += 1;

		/* Force line break after option with value. */
		line_len = PCF_LINE_LIMIT;
	    }
	}
    }
    vstream_fputs("\n", fp);

    if (msg_verbose)
	vstream_fflush(fp);
}
Beispiel #12
0
Value *
read_num_or_symbol(Globals *g)
{
   Value *v;
   int strpos = 0;
   char c;
   int i;
   int is_integer;

#define ADD_CHAR(c)	\
   if (strpos >= g->strbuflen) \
      expand_strbuf(g);		\
   g->strbuf[strpos++] = (c)

   while (g->buflen > 0) {
      switch (PEEK_CHAR(g)) {
       case ' ':
       case '\t':
       case '\n':
       case '\0':
       case '\"':
       case '(':
       case ')':
       case '.':
	 goto done;
	 break;
       case '\\':
	 NEXT_CHAR(g);
	 ADD_CHAR(PEEK_CHAR(g));
	 NEXT_CHAR(g);
	 break;
       default:
	 ADD_CHAR(PEEK_CHAR(g));
	 NEXT_CHAR(g);
	 break;
      }
   }
   ABORT(g, 23);

 done:
   /* is this a number or a symbol? */
   /* assume integer to start */
   is_integer = 1;

   /* assume no empty strings? */

   /* if the first character is '+' or '-' and that's not the only */
   /* character it can still be an integer */
   if (strpos > 1 && (g->strbuf[0] == '-' || g->strbuf[0] == '+'))
      i = 1;
   else if (strpos == 1) {
      i = 0;
      is_integer = 0;
   }
   else
      i = 0;

   while (is_integer && i < strpos) {
      if (g->strbuf[i] < '0' || g->strbuf[i] > '9')
	 is_integer = 0;
      i++;
   }

   if (is_integer) {
      /* it's an integer */
      v = ALLOC_VALUE();
      v->tag = integer;
      ADD_CHAR('\0');
      v->value.integer.i = atoi(g->strbuf);
   }
   else {
      /* it's a symbol */
      if (3 == strpos &&
	  !bcmp(g->strbuf, "nil", 3)) {
	 v = NULL;
      } else {
	 v = ALLOC_VALUE();
	 v->tag = symbol;
	 v->value.s.length = strpos;
	 v->value.s.string = (char *) malloc(v->value.s.length);
	 bcopy(g->strbuf, v->value.s.string, v->value.s.length);
      }
   }
   return v;
}
Beispiel #13
0
const CommMessage_t *
comm_parse (uint8_t *data, uint8_t len)
{
    uint8_t i = 0;
    uint8_t msg_received = FALSE;

    while ( (i < len) && !msg_received ) 
    {
        uint8_t c = data[i++];
        switch (rxstatus.parse_state) 
        {
            case STATE_UNINIT:
                if (c == COMM_STX) {
                    rxstatus.parse_state++;
                    rxmsg.ck_a = COMM_STX;
                    rxmsg.ck_b = COMM_STX;
                }
                break;
            case STATE_GOT_STX:
                if (msg_received) {
                    rxstatus.buffer_overrun++;
                    goto error;
                }
                /* Counting STX, LENGTH, ACID, MSGID, CRC1 and CRC2 */
                rxmsg.len = c - COMM_NUM_NON_PAYLOAD_BYTES; 
                rxmsg.idx = 0;
                UPDATE_CHECKSUM(rxmsg, c)
                rxstatus.parse_state++;
                break;
            case STATE_GOT_LENGTH:
                rxmsg.acid = c;
                UPDATE_CHECKSUM(rxmsg, c)
                rxstatus.parse_state++;
                break;
            case STATE_GOT_ACID:
                rxmsg.msgid = c;
                UPDATE_CHECKSUM(rxmsg, c)
                if (rxmsg.len == 0)
                    rxstatus.parse_state = STATE_GOT_PAYLOAD;
                else
                    rxstatus.parse_state++;
                break;
            case STATE_GOT_MSGID:
                ADD_CHAR(rxmsg, c)
                UPDATE_CHECKSUM(rxmsg, c)
                if (rxmsg.idx == rxmsg.len)
                    rxstatus.parse_state++;
                break;
            case STATE_GOT_PAYLOAD:
                if (c != rxmsg.ck_a)
                    goto error;
                rxstatus.parse_state++;
                break;
            case STATE_GOT_CRC1:
                if (c != rxmsg.ck_b)
                    goto error;
                /* Successfully got message */
                msg_received = TRUE;
                goto restart;
        }
        continue;
        error:
            rxstatus.parse_error++;
        restart:
            rxstatus.parse_state = STATE_UNINIT;
        break;
    }
    return (msg_received ? &rxmsg : NULL);
}
Beispiel #14
0
int vsnprintf(char *s, unsigned int n, const char *fmt, va_list ap)
{
    char l_tmp[256];

    if (n == 0)
        return 0;

    if (n == 1) {
        s[0] = 0;
        return 0;
    }

    int i = 0;
    int ret = 0;

    for (const char *p = fmt; *p; p++) {
        if (*p != '%') {
            ADD_CHAR(*p);
            continue;
        }

        INCREMENT_P;

        /* flags */

        int flags = 0;

        if (*p == '#') {
            flags |= FLG_HASH_SIGN;

            INCREMENT_P;
        }

        if (*p == '-') {
            flags |= FLG_MINUS_SIGN;

            INCREMENT_P;
        }

        /* width */

        int width = 0;
        bool pad0 = false;

        if (*p == '0') {
            pad0 = true;
            INCREMENT_P;
        }

        while ('0' <= *p && *p <= '9') {
            width *= 10;
            width += *p - '0';

            INCREMENT_P;
        }

        if (*p == '*') {
           width = va_arg(ap, int);

           INCREMENT_P;
        }

        /* precision */

        unsigned int precision = 0;

        if (*p == '.') {
            INCREMENT_P;

            if (*p == '*') {
               precision = va_arg(ap, int);

               INCREMENT_P;
            } else {