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; } } }
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; }
/** * 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 }
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; }
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)}
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; }
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)&¤t_ch!='\n'&¤t_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 */ }
/* * 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() */
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); }
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; }
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); }
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 {