Esempio n. 1
0
const char * stristr(const char * str1, const char * str2)
{
	if (!*str2) return str1;
	for (const char * cp = str1; *cp; cp++) {
		const char * s2 = str2;
		for (const char * s1 = cp; *s1 && *s2 && (IS_ALPHA(*s1) && IS_ALPHA(*s2)) ? !(TO_UPPER(*s1) - TO_UPPER(*s2)) : !(*s1 - *s2); s1++)
			++s2;
		if (!*s2)
			return cp;
	}
	return nullptr;
}
Esempio n. 2
0
NLM_EXTERN size_t Nlm_stream2text(const Nlm_Char FAR PNTR str, size_t max_col,
                                  int PNTR dash)
{
  const Nlm_Char FAR PNTR s;
  const Nlm_Char FAR PNTR sb; /* the nearest breakable position */
  size_t n_lead = 0;
  size_t n_tail = 0;

  size_t len = Nlm_StringLen( str );
  len = max_col < len ? max_col : len;

  *dash = 0;
  if (len == 0  ||  can_break(str[len-1], str[len]))
    return len;

  /* go to the beginning of the last completely fit word */
  for (sb = &str[len-1];
       sb != str  &&  !IS_WHITESP(*sb)  &&  !can_break(*sb, *(sb+1));
       sb--) continue;
  while (sb != str  &&  IS_WHITESP(*sb))
    sb--;

  if (sb == str)
    { /* the first word is longer than "max_col" */
      if (len > MAX_NO_DASH  &&  IS_ALPHA(str[len-1])  &&  IS_ALPHA(str[len]))
        *dash = 1;  /* recommend use dash in the place of last symbol */

      return len;
    }

  /* decide of whether and how to break the last alphabet word */

  /*  count the lead and the tail of the last non-fit word */
  for (s = &str[len];  *s != '\0'  &&  IS_ALPHA(*s);  s++, n_tail++) continue;
  for (s = &str[len-1];  IS_ALPHA(*s);  s--, n_lead++) continue;
  ASSERT ( s > str );

  /* try to "move" symbols from lead in the sake of tail */
  while (n_lead > MIN_LEAD  &&  n_tail < MIN_TAIL)  {
    n_lead--;
    n_tail++;
  }

  if (n_lead < MIN_LEAD  ||  n_tail < MIN_TAIL)
    { /* no luck this time -- move the whole non-fit word to the next line */
      return (sb - str + 1);
    }
  else
    {
      *dash = 1;
      return (s - str + n_lead + 1);
    }
}
Esempio n. 3
0
static char * dir_ConvertDescriptionToPrefName(DIR_Server * server)
{
#define MAX_PREF_NAME_SIZE 25
  char * fileName = nsnull;
  char fileNameBuf[MAX_PREF_NAME_SIZE];
  PRInt32 srcIndex = 0;
  PRInt32 destIndex = 0;
  PRInt32 numSrcBytes = 0;
  const char * descr = nsnull;
  if (server && server->description)
  {
    descr = server->description;
    numSrcBytes = PL_strlen(descr);
    while (srcIndex < numSrcBytes && destIndex < MAX_PREF_NAME_SIZE-1)
    {
      if (IS_DIGIT(descr[srcIndex]) || IS_ALPHA(descr[srcIndex]))
      {
        fileNameBuf[destIndex] = descr[srcIndex];
        destIndex++;
      }

      srcIndex++;
    }

    fileNameBuf[destIndex] = '\0'; /* zero out the last character */
  }

  if (destIndex) /* have at least one character in the file name? */
  fileName = strdup(fileNameBuf);

  return fileName;
}
Esempio n. 4
0
File: xskip.c Progetto: mrmt/enma
/*
 * [RFC4871]
 * hyphenated-word =  ALPHA [ *(ALPHA / DIGIT / "-") (ALPHA / DIGIT) ]
 */
int
XSkip_hyphenatedWord(const char *head, const char *tail, const char **nextp)
{
    const char *p = head;

    *nextp = p;
    // 先頭の文字は ALPHA
    if (tail <= p || !IS_ALPHA(*p)) {
        return *nextp - head;
    }   // end if

    for (++p; p < tail; ++p) {
        if (IS_LET_DIG(*p)) {
            *nextp = p;
            continue;
        }   // end if
        if ('-' == *p) {    // '-' は終端にならない
            continue;
        }   // end if
        break;
    }   // end for

    ++(*nextp);
    return *nextp - head;
}   // end function : XSkip_hyphenatedWord
Esempio n. 5
0
File: regex.c Progetto: fiery-/w3m
static int
match_range_longchar(longchar * a, longchar * b, longchar * c, int ignore)
{
#ifdef USE_M17N
    if (a->type != b->type || a->type != c->type)
	return 0;
    if (a->type == RE_TYPE_WCHAR_T) {
	if (a->wch.ccs != c->wch.ccs || c->wch.ccs != b->wch.ccs)
	    return 0;
#ifdef USE_UNICODE
	if (ignore) {
	    wc_uint32 uc = wc_any_to_ucs(c->wch);

	    if (wc_is_ucs_alpha(uc)) {
	    	wc_uint32 ua = wc_any_to_ucs(a->wch);
	    	wc_uint32 ub = wc_any_to_ucs(b->wch);
		wc_uint32 upper = wc_ucs_toupper(uc);
		wc_uint32 lower = wc_ucs_tolower(uc);
		wc_uint32 title = wc_ucs_totitle(uc);

		return ((ua <= upper && upper <= ub) ||
			(ua <= lower && lower <= ub) ||
			(ua <= title && title <= ub));
	    }
	}
#endif
	return (a->wch.code <= c->wch.code && c->wch.code <= b->wch.code);
    }
#endif
    if (ignore && IS_ALPHA(c->ch))
	return ((a->ch <= TOLOWER(c->ch) && TOLOWER(c->ch) <= b->ch) ||
		(a->ch <= TOUPPER(c->ch) && TOUPPER(c->ch) <= b->ch));
    else
	return (a->ch <= c->ch && c->ch <= b->ch);
}
Esempio n. 6
0
static BioseqPtr DOT_GetBspFromGIOrAcc(CharPtr str)
{
   BioseqPtr  bsp;
   Int4       gi;
   Char       ptr;
   SeqIdPtr   sip;
   ValNode    vn;
   LinkSetPtr lsp;
   Int4       uid;

   str = TrimSpacesAroundString(str);
   ptr = *str;
   if (IS_ALPHA(ptr))  /* accession */
   {
      sip = SeqIdFromAccessionDotVersion(str);   
      bsp = BioseqLockById(sip);
   } else  /* it's a GI */
   {
      gi = atoi(str);
      vn.choice = SEQID_GI;
      vn.data.intvalue = gi;
      vn.next = NULL;
      bsp = BioseqLockById(&vn);
   }
   return bsp;
}
Esempio n. 7
0
/*****************************************************************************
*   CkLabelType:
*	checks /label=,feature_label> or /label=<base_range>
*                                                          -Tatiana 1/28/95
******************************************************************************/
NLM_EXTERN CharPtr CkLabelType(CharPtr str)
{
	Boolean range = TRUE, label = TRUE;
	CharPtr		bptr;
	
	if (IS_DIGIT(*str)) {
		for (; IS_DIGIT(*str); str++)
			continue;
		if (*str == '.' && *(str+1) == '.') {
			str += 2;
			if (!IS_DIGIT(*str)) {
				range = FALSE;
			} else {
				while (IS_DIGIT(*str)) {
					str++;
				}
			}
			if (*str != '\0') {
				range = FALSE;
			}
		} else {
			range = FALSE;
		}
		
	} 
	if (!range) {
		bptr = str;
		for (;  *str != '\0' && !IS_ALPHA(*str); str++)
			continue;
		if (*str == '\0') {
			label = FALSE;    /* must be at least one letter */
		}
		for (str = bptr; *str != '\0' && IS_ALPHA(*str) || IS_DIGIT(*str) 
			|| *str == '-' || *str == '_' || *str == '\'' || *str == '*';
			str++)
			continue;
		if (*str != '\0') {
			label = FALSE;
		}
	}
	if (range || label) {
		return NULL;
	} else {
		return str;
	}
}
Esempio n. 8
0
/*
 * Convert a string into a valid C identifier by replacing invalid
 * characters with '_'.  Also makes sure the string is nul-terminated
 * and takes up at most n bytes.
 */
void
strident_canon(char *s, size_t n)
{
	char c;
	char *end = s + n - 1;

	if ((c = *s) == 0)
		return;

	if (!IS_ALPHA(c) && c != '_')
		*s = '_';

	while (s < end && ((c = *(++s)) != 0)) {
		if (!IS_ALPHA(c) && !IS_DIGIT(c) && c != '_')
			*s = '_';
	}
	*s = 0;
}
Esempio n. 9
0
/***************************************************************************
*
*  SPI_ReadFeatureTable reads in a tab-delimited file and converts it
*  to feature information:
*
*  sequence id	name of feature		start	stop
*  NM_004377.1	repetitive_region	12	40
*
*  Masking and other feature information for all mRNAs should be in the
*  same file; ids not in the mRNA list or unknown feature names will be
*  ignored.
*
***************************************************************************/
static void SPI_ReadFeatureTable(FILE *ifp, SPI_bsinfoPtr spim_head)
{
   Char           c;
   CharPtr        fields[5];
   Boolean        found;
   Char           line[60];
   Int4           i;
   CharPtr        ptr;
   SeqIdPtr       sip;
   SeqLocPtr      slp;
   SPI_bsinfoPtr  spim;
   CharPtr        str;
   ValNode        vn;

   str = ReadALine(line, sizeof(line), ifp);
   while (str != NULL)
   {
      ptr = strtok(str, " \t");
      for (i=0; i<4; i++)
      {
         fields[i] = StringSave(ptr);
         ptr = strtok(NULL, " \t");
      }
      if (fields[1] != NULL && !StrCmp(fields[1], "repetitive_region"))
      {
         c = *fields[0];
         if (IS_ALPHA(c))
            sip = SeqIdFromAccessionDotVersion(fields[0]);
         else
         {
            vn.choice = SEQID_GI;
            vn.data.intvalue = atoi(fields[0]);
            vn.next = NULL;
            sip = &vn;
         }
         spim = spim_head;
         found = FALSE;
         while (!found && spim != NULL)
         {
            if (SeqIdIn(sip, spim->bsp->id) == TRUE)
               found = TRUE;
            else
               spim = spim->next;
         }
         if (found)
         {
            slp = SeqLocIntNew(atoi(fields[2]), atoi(fields[3]), Seq_strand_both, spim->bsp->id);
            slp->next = spim->lcaseloc;
            spim->lcaseloc = slp;
         }
      }
      str = ReadALine(line, sizeof(line), ifp);
   }
}
Esempio n. 10
0
static int
is_valid_ident(const char *s, const char *e, int allowdot)
{
	char c;

	if (s >= e)
		return (0);		/* name is empty */

	c = *s++;
	if (!IS_ALPHA(c))
		return (0);		/* does not start with letter */

	while (s < e && (c = *s++) != 0) {
		if (IS_ALPHA(c) || IS_DIGIT(c) || c == '-' || c == '_' ||
		    (allowdot && c == '.'))
			continue;
		return (0);		/* invalid character */
	}
	return (1);
}
Esempio n. 11
0
/*************************************************************************
***
*	gb_id_make(): make the Seq-id for Genbank with tsip->name = name
*	tsip->acc.
*
*************************************************************************
***/
NLM_EXTERN SeqIdPtr gb_id_make(CharPtr name, CharPtr acc)
{
   SeqIdPtr new_id;
   TextSeqIdPtr tsip;

	   new_id= (SeqIdPtr)ValNodeNew(NULL);
	   new_id->choice = SEQID_GENBANK;
	   tsip = TextSeqIdNew();
	   if(name)
	   {
	   if(StringLen(name) >3 && IS_ALPHA(name[0]))
	     tsip->name = StringSave(name);
	   }
	   if(acc)
	   {
	   if(StringLen(acc) >3 && IS_ALPHA(acc[0]))
	     tsip->accession = StringSave(acc);
	   }
	   new_id->data.ptrvalue = tsip;
	   return new_id;
}
Esempio n. 12
0
File: xskip.c Progetto: mrmt/enma
/*
 * [RFC4408]
 * name = ALPHA *( ALPHA / DIGIT / "-" / "_" / "." )
 */
int
XSkip_spfName(const char *head, const char *tail, const char **nextp)
{
    const char *p = head;

    // 先頭の文字は ALPHA
    if (tail <= p || !IS_ALPHA(*p)) {
        *nextp = p;
        return *nextp - head;
    }   // end if

    for (++p; p < tail && IS_SPF_NAME(*p); ++p);
    *nextp = p;
    return *nextp - head;
}   // end function : XSkip_spfName
Esempio n. 13
0
File: xskip.c Progetto: mrmt/enma
/*
 * [RFC4871]
 * x-sig-a-tag-k   = ALPHA *(ALPHA / DIGIT)   ; for later extension
 * x-sig-a-tag-h   = ALPHA *(ALPHA / DIGIT)   ; for later extension
 */
int
XSkip_alphaAlnum(const char *head, const char *tail, const char **nextp)
{
    const char *p = head;

    // 先頭の文字は ALPHA
    if (tail <= p || !IS_ALPHA(*p)) {
        *nextp = p;
        return *nextp - head;
    }   // end if

    for (++p; p < tail && IS_ALNUM(*p); ++p);

    *nextp = p;
    return *nextp - head;
}   // end function : XSkip_alphaAlnum
Esempio n. 14
0
NLM_EXTERN Nlm_CharPtr LIBCALL Nlm_text2stream(const Nlm_Char FAR PNTR str)
{
  int on_space = 0;
  Nlm_CharPtr line, s;

  if ( !str )
    return NULL;

  while (*str  &&  IS_WHITESP( *str ))
    str++;
  if ( !*str )
    return NULL;

  s = line = (Nlm_CharPtr) Nlm_MemNew(Nlm_StringLen(str) + 1);

  for (  ;  *str;  str++)
    {
      if ( IS_WHITESP(*str) )
        {
          if (*str == '\n')
            *s = '\n';
          on_space = 1;
        }
      else
        {
          if ( on_space ) {
            if (*s == '\n'  &&
                s - line > 1  &&  *(s-1) == '-'  &&  IS_ALPHA(*(s-2)))
              {
                *s = '\0';
                s--;  /* eat dash before end-of-line, merge the broken word */
              }
            else
              *s++ = SPACE;

            *s++ = *str;
            on_space = 0;
          }
          else
            *s++ = *str;
        }
    }
  *s = '\0';

  return (Nlm_CharPtr) realloc(line, Nlm_StringLen(line) + 1);
}
Esempio n. 15
0
/**
 * Reads a name from the cache
 *
 * Description:
 * 		Name	   		::=   	NameStartChar (NameChar)*
 * 		NameStartChar	::=   	":" | [A-Z] | "_" | [a-z]	//add "?"
 * 		NameChar	   	::=   	NameStartChar | "-" | "." | [0-9]
 * @param var
 * @return RES_OK if the char was skipped, RES_EOF if no more tags, errors..
 */
RES_CODE CCache::get_name(CSTRING& var)
{
	char ch;
	RES_CODE res;

	res = get_pc(ch);
	if (res == RES_OK)
	{
		if (ch == ':' || ch == '_' || ch == '?' || IS_ALPHA(ch))
		{
			var += ch;

			while (!var.empty())
			{
				res = getc(ch);
				switch (res)
				{
				case RES_OK:
					if (ch == ':' || ch == '_' || ch == '-' || ch == '.'
							|| IS_ALPHANUM(ch))
					{
						var += ch;
					}
					else
					{
						ungetc();
						return RES_OK;
					}
					break;

				case RES_EOF:
					return RES_OK;

				default:
					return (res);
				}

			}
			return RES_OUT_OF_MEMORY;
		}
		ungetc();
		res = RES_INVALID_DATA;
	}
	return (res);
}
Esempio n. 16
0
File: regex.c Progetto: fiery-/w3m
static int
match_longchar(longchar * a, longchar * b, int ignore)
{
#ifdef USE_M17N
    if (a->type != b->type)
	return 0;
    if (a->type == RE_TYPE_WCHAR_T) {
#ifdef USE_UNICODE
	if (ignore) {
	    wc_uint32 ua = wc_any_to_ucs(a->wch), ub = wc_any_to_ucs(b->wch);
	    return (ua == ub ||
		    ua == wc_ucs_tolower(ub) ||
	            ua == wc_ucs_toupper(ub) ||
		    ua == wc_ucs_totitle(ub));
	}
#endif
	return (a->wch.ccs == b->wch.ccs) && (a->wch.code == b->wch.code);
    }
#endif
    if (ignore && IS_ALPHA(b->ch))
	return (a->ch == TOLOWER(b->ch) || a->ch == TOUPPER(b->ch));
    else
	return a->ch == b->ch;
}
Esempio n. 17
0
File: xskip.c Progetto: mrmt/enma
/*
 * [RFC5234]
 * ALPHA =  %x41-5A / %x61-7A   ; A-Z / a-z
 */
int
XSkip_alpha(const char *head, const char *tail, const char **nextp)
{
    *nextp = (head < tail && IS_ALPHA(*head)) ? head + 1 : head;
    return *nextp - head;
}   // end function : XSkip_alpha
Esempio n. 18
0
Int4 BE_ReadIds(BEDataPtr pBdata, Uint4 **ids_out)
{
    Uint4 *uids, *giptr;
    Int4 length, NumNotValid = 0, gi;
    Int4 i, j, k, allocated, count = 0;
    Char TmpBuff[16];
    CharPtr buffer;

    if((buffer = pBdata->uids) == NULL || *buffer == NULLB) {
        *ids_out = NULL;
        return 0;
    }
    
    length = StringLen(buffer);
    
    allocated = UID_BUFF_SIZE;
    uids = (Uint4 *)MemNew(allocated * sizeof(Uint4));

    for(i = 0; i < length; i++) {
        
        if(isspace(buffer[i]) || buffer[i] == ',') /* Rolling spaces */
            continue;
        
        /* This is defence from badly formatted requests */
        
        if(NumNotValid > 10) {
            printf("**** ERROR: Too many invalid Gis/Accessions, "
                   "parsing aborted\n");
            *ids_out = NULL;
            return 0;
        }
        
        /* Rolling spaces */
        
        j= 0;
        while (!isspace(buffer[i]) && j < 10  && i < length) { 
            TmpBuff[j] = buffer[i];
            j++; i++;
            if(buffer[i] == ',')  /* Comma is valid delimiter */
                break;
        }
        TmpBuff[j] = NULLB;
        
        
        /* Ignore strings like ">Protein" */
        
        if(j > 0 && TmpBuff[0] == '>' && IS_ALPHA(TmpBuff[1]))
            continue;
        
        /* Is gi/accession too long ??? */
        
        if(j == 10) {
            NumNotValid++;
            
            while(!isspace(buffer[i]) || 
                  buffer[i] == ',' || 
                  buffer[i] == NULLB) /* Rolling until spaces */
                i++;
            continue;  /* Next may be valid ... who knows...?? */   
        }
        
        /* Now validating accession/gi */
        
        for(k =0; k < j; k++) {
            if(!isdigit(TmpBuff[k])) {
                break;
            }
        }
        if(k != j) { 
            if(!IS_ntdb_accession(TmpBuff) && !IS_protdb_accession(TmpBuff)) {
                NumNotValid++;
                printf("**** WARNING: Gi/Accession \"%s\" is not valid\n", 
                       TmpBuff);
                continue;
            }
        }
        
        /* If this is valid Accession check and tranfer it to gi */
        
        giptr = NULL;

        if((gi = BEAccessionToGi (TmpBuff)) < 0) {
            printf("**** WARNING: Gi/Accession %s is not found "
                   "in database----\r\n", TmpBuff);
            /* NumNotValid++; */
            continue;
        } else {
            if(count == allocated) {
                allocated += UID_BUFF_SIZE;
                uids = (Uint4*)Realloc(uids, allocated * sizeof(Uint4));
            }
            uids[count] = gi;
            count++;
        }
    }

    if(NumNotValid) {
        printf("**** %d invalid Gi%s/Accession%s present in Entrez-batch "
               "request\r\n", 
               (int)NumNotValid,
               NumNotValid == 1 ? "" : "s",
               NumNotValid == 1 ? "" : "s"
               );
    }
    
    *ids_out = uids;
    return count;    
}
Esempio n. 19
0
/**
 * Identifies the next token in the input stream. When the function starts, the
 * cursor points to the beginning of the token to identify. When the function
 * returns, the cursor points to the beginning of the next token, one character
 * past the end of the current token. The return value is an enum indicating
 * the identified token's type. Since this function also identifies non-syntax
 * elements such as whitespace and comments, additional filtering may be useful.
 */
Token lex(char const **p, char const *end)
{
  if (end <= *p) {
    return LEX_END;
  /* Whitespace: */
  } else if (IS_SPACE(**p)) {
    do {
      ++*p;
    } while (*p < end && IS_SPACE(**p));
    return LEX_WHITESPACE;
  /* Newline: */
  } else if (**p == '\n' || **p == '\f') {
    ++*p;
    return LEX_NEWLINE;
  } else if (**p == '\r') {
    ++*p;
    if (*p < end && **p == '\n')
      ++*p;
    return LEX_NEWLINE;
  /* Comments: */
  } else if (**p == '/') {
    ++*p;
    if (end <= *p) return LEX_SLASH;
    /* C++ style comments: */
    if (**p == '/') {
      do {
        ++*p;
      } while (*p < end && !IS_NEWLINE(**p));
      return LEX_COMMENT;
    /* C style comments: */
    } else if (**p == '*') {
      do {
        do {
          ++*p;
          if (end <= *p) return LEX_ERROR_END;
        } while (**p != '*');
        do {
          ++*p;
          if (end <= *p) return LEX_ERROR_END;
        } while (**p == '*');
      } while (**p != '/');
      ++*p;
      return LEX_COMMENT;
    /* Lone slash: */
    } else {
      return LEX_SLASH;
    }
  /* Double-quoted string literal: */
  } else if (**p == '\"') {
    do {
      ++*p;
      if (end <= *p) return LEX_ERROR_END;
      if (**p == '\\') {
        ++*p;
        if (end <= *p) return LEX_ERROR_END;
        ++*p;
        if (end <= *p) return LEX_ERROR_END;
      }
    } while (**p != '\"');
    ++*p;
    return LEX_STRING;
  /* Single-quoted character literal: */
  } else if (**p == '\'') {
    do {
      ++*p;
      if (end <= *p) return LEX_ERROR_END;
      if (**p == '\\') {
        ++*p;
        if (end <= *p) return LEX_ERROR_END;
        ++*p;
        if (end <= *p) return LEX_ERROR_END;
      }
    } while (**p != '\'');
    ++*p;
    return LEX_CHAR;
  /* Numeric literals (including malformed ones, which are ignored): */
  } else if ('0' <= **p && **p <= '9') {
    do {
      ++*p;
    } while (*p < end && IS_ALPHANUM(**p));
    return LEX_NUMBER;
  /* Identifiers: */
  } else if (IS_ALPHA(**p)) {
    do {
      ++*p;
    } while (*p < end && IS_ALPHANUM(**p));
    return LEX_IDENTIFIER;
  /* Token-pasting: */
  } else if (**p == '\\') {
    ++*p;
    if (end <= *p) return LEX_BACKSLASH;
    if (**p == '\\') {
      ++*p;
      return LEX_PASTE;
    } else if (**p == 'o') {
      ++*p;
      if (*p < end && **p == 'l') {
        ++*p;
        return LEX_ESCAPE;
      } else {
        --*p;
        return LEX_BACKSLASH;
      }
    }
    return LEX_BACKSLASH;
  /* Symbols: */
  } else if (**p == '!') { ++*p; return LEX_BANG;
  } else if (**p == '&') { ++*p; return LEX_AMP;
  } else if (**p == '(') { ++*p; return LEX_PAREN_L;
  } else if (**p == ')') { ++*p; return LEX_PAREN_R;
  } else if (**p == '*') { ++*p; return LEX_STAR;
  } else if (**p == ',') { ++*p; return LEX_COMMA;
  } else if (**p == '.') { ++*p; return LEX_DOT;
  /* LEX_SLASH was recognized earlier. */
  } else if (**p == ';') { ++*p; return LEX_SEMICOLON;
  } else if (**p == '<') { ++*p; return LEX_LT;
  } else if (**p == '=') { ++*p; return LEX_EQUALS;
  } else if (**p == '>') { ++*p; return LEX_GT;
  /* LEX_BACKSLASH was recognized earlier. */
  } else if (**p == '{') { ++*p; return LEX_BRACE_L;
  } else if (**p == '|') { ++*p; return LEX_PIPE;
  } else if (**p == '}') { ++*p; return LEX_BRACE_R;
  /* Any other character: */
  } else {
    ++*p;
    return LEX_ERROR;
  }
}
Esempio n. 20
0
/*
  Initialise: Open the Android NVM device and find the partitions on it. Save them in
  a list along with the "PartitionName" fields for their GPT entries.
  We will use these partition names as the key in
  ArmFastbootPlatformFlashPartition.
*/
EFI_STATUS
ArmFastbootPlatformInit (
  VOID
  )
{
  EFI_STATUS                          Status;
  EFI_DEVICE_PATH_PROTOCOL           *FlashDevicePath;
  EFI_DEVICE_PATH_PROTOCOL           *FlashDevicePathDup;
  EFI_DEVICE_PATH_PROTOCOL           *DevicePath;
  EFI_DEVICE_PATH_PROTOCOL           *NextNode;
  HARDDRIVE_DEVICE_PATH              *PartitionNode;
  UINTN                               NumHandles;
  EFI_HANDLE                         *AllHandles;
  UINTN                               LoopIndex;
  EFI_HANDLE                          FlashHandle;
  EFI_BLOCK_IO_PROTOCOL              *FlashBlockIo;
  EFI_PARTITION_ENTRY                *PartitionEntries;
  FASTBOOT_PARTITION_LIST            *Entry;

  InitializeListHead (&mPartitionListHead);

  //
  // Get EFI_HANDLES for all the partitions on the block devices pointed to by
  // PcdFastbootFlashDevicePath, also saving their GPT partition labels.
  // There's no way to find all of a device's children, so we get every handle
  // in the system supporting EFI_BLOCK_IO_PROTOCOL and then filter out ones
  // that don't represent partitions on the flash device.
  //

  FlashDevicePath = ConvertTextToDevicePath ((CHAR16*)FixedPcdGetPtr (PcdAndroidFastbootNvmDevicePath));

  //
  // Open the Disk IO protocol on the flash device - this will be used to read
  // partition names out of the GPT entries
  //
  // Create another device path pointer because LocateDevicePath will modify it.
  FlashDevicePathDup = FlashDevicePath;
  Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &FlashDevicePathDup, &FlashHandle);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "Warning: Couldn't locate Android NVM device (status: %r)\n", Status));
    // Failing to locate partitions should not prevent to do other Android FastBoot actions
    return EFI_SUCCESS;
  }

  Status = gBS->OpenProtocol (
                  FlashHandle,
                  &gEfiBlockIoProtocolGuid,
                  (VOID **) &FlashBlockIo,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "Fastboot platform: Couldn't open Android NVM device (status: %r)\n", Status));
    return EFI_DEVICE_ERROR;
  }

  // Read the GPT partition entry array into memory so we can get the partition names
  Status = ReadPartitionEntries (FlashBlockIo, &PartitionEntries);
  if (EFI_ERROR (Status)) {
	DEBUG ((EFI_D_ERROR, "Warning: Failed to read partitions from Android NVM device (status: %r)\n", Status));
	// Failing to locate partitions should not prevent to do other Android FastBoot actions
	return EFI_SUCCESS;
  }

  // Get every Block IO protocol instance installed in the system
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiBlockIoProtocolGuid,
                  NULL,
                  &NumHandles,
                  &AllHandles
                  );
  ASSERT_EFI_ERROR (Status);

  // Filter out handles that aren't children of the flash device
  for (LoopIndex = 0; LoopIndex < NumHandles; LoopIndex++) {
    // Get the device path for the handle
    Status = gBS->OpenProtocol (
                    AllHandles[LoopIndex],
                    &gEfiDevicePathProtocolGuid,
                    (VOID **) &DevicePath,
                    gImageHandle,
                    NULL,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    ASSERT_EFI_ERROR (Status);

    // Check if it is a sub-device of the flash device
    if (!CompareMem (DevicePath, FlashDevicePath, FLASH_DEVICE_PATH_SIZE (FlashDevicePath))) {
      // Device path starts with path of flash device. Check it isn't the flash
      // device itself.
      NextNode = NextDevicePathNode (DevicePath);
      if (IsDevicePathEndType (NextNode)) {
        continue;
      }

      // Assert that this device path node represents a partition.
      ASSERT (NextNode->Type == MEDIA_DEVICE_PATH &&
              NextNode->SubType == MEDIA_HARDDRIVE_DP);

      PartitionNode = (HARDDRIVE_DEVICE_PATH *) NextNode;

      // Assert that the partition type is GPT. ReadPartitionEntries checks for
      // presence of a GPT, so we should never find MBR partitions.
      // ("MBRType" is a misnomer - this field is actually called "Partition
      //  Format")
      ASSERT (PartitionNode->MBRType == MBR_TYPE_EFI_PARTITION_TABLE_HEADER);

      // The firmware may install a handle for "partition 0", representing the
      // whole device. Ignore it.
      if (PartitionNode->PartitionNumber == 0) {
        continue;
      }

      //
      // Add the partition handle to the list
      //

      // Create entry
      Entry = AllocatePool (sizeof (FASTBOOT_PARTITION_LIST));
      if (Entry == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        FreePartitionList ();
        goto Exit;
      }

      // Copy handle and partition name
      Entry->PartitionHandle = AllHandles[LoopIndex];
      StrnCpy (
        Entry->PartitionName,
        PartitionEntries[PartitionNode->PartitionNumber - 1].PartitionName, // Partition numbers start from 1.
        PARTITION_NAME_MAX_LENGTH
        );
      InsertTailList (&mPartitionListHead, &Entry->Link);

      // Print a debug message if the partition label is empty or looks like
      // garbage.
      if (!IS_ALPHA (Entry->PartitionName[0])) {
        DEBUG ((EFI_D_ERROR,
          "Warning: Partition %d doesn't seem to have a GPT partition label. "
          "You won't be able to flash it with Fastboot.\n",
          PartitionNode->PartitionNumber
          ));
      }
    }
  }

Exit:
  FreePool (PartitionEntries);
  FreePool (FlashDevicePath);
  FreePool (AllHandles);
  return Status;

}
Esempio n. 21
0
NLM_EXTERN Int4 print_protein_for_cds(SeqFeatPtr sfp, CharPtr buf, SeqLocPtr loc, Boolean reverse_minus)
{
	CdRegionPtr crp;
	Int4 frame_offset, start_offset;
	Uint1 f_strand;
	Boolean reverse;
	Int4 cd_len;
	GatherRange gr;
	Int2 p_pos, buf_len;
	Int4 a_left, a_right;
	Int4 aa, val;
	SeqLocPtr slp;
	SeqPortPtr spp;
	ByteStorePtr p_data;
	Int4 end_pos, start_pos = -1;
	Uint1 residue;
	Boolean seal_ends = FALSE;
	Boolean reverse_order;

	if(sfp == NULL || sfp->data.choice != 3)
		return -1;
	if(buf == NULL || loc == NULL)
		return -1;
	crp = sfp->data.value.ptrvalue;
	if(crp == NULL)
		return -1;

	if(buf[0] == '\0')
		seal_ends = TRUE;
	spp = NULL;
	p_data = NULL;
	if(sfp->product !=NULL && !IS_BOGO_Product(sfp->ext))
	{
		spp = SeqPortNewByLoc(sfp->product, Seq_code_ncbieaa);
		if(spp !=NULL)
		{
    			SeqPortSeek(spp, 0, SEEK_SET);
			end_pos = spp->totlen-1;
		}
	}
	if(spp == NULL)
	{
		p_data = ProteinFromCdRegion(sfp, TRUE);
		/* p_data = ProteinFromCdRegion(sfp, FALSE); */
		if(p_data !=NULL)
		{
			BSSeek(p_data, 0, SEEK_SET);
			end_pos = BSLen(p_data)-1;
		}
	}

	if(spp == NULL && p_data == NULL)
		return -1;

	if(crp->frame == 0)
		frame_offset = 0;
	else
		frame_offset = (Int4)crp->frame-1;
	start_offset = frame_offset;

	f_strand = SeqLocStrand(sfp->location);
	reverse = ck_reverse(f_strand, SeqLocStrand(loc));
	/*if reverse == TRUE, the translated protein is written backwards*/
	if(reverse && reverse_minus)
		reverse_order = TRUE;
	else
		reverse_order = FALSE;
	
	slp = NULL;
	cd_len = 0;
	aa = 0;

        buf_len = SeqLocLen(loc);

	if(reverse_order)
	{
		p_pos = buf_len -1;
		if(seal_ends)
		{
			buf[p_pos+1] = '\0';
			seal_ends = FALSE;
		}
	}
	else
		p_pos = 0;

	while((slp = SeqLocFindNext(sfp->location, slp))!=NULL)
	{
	   if(SeqLocOffset(loc, slp, &gr, 0))
	   {
		if(reverse_order)
		{
			if(gr.right < p_pos)
				p_pos = (Int2)(gr.right);
		}
		else
		{
			if(p_pos < gr.left)
				p_pos = (Int2)(gr.left);
		}
		SeqLocOffset(slp, loc, &gr, 0);
		
		a_left = gr.left + cd_len;
		a_right = gr.right + cd_len;
		/* if(reverse_order)
		{
			temp = a_right;
			a_right = -a_left;
			a_left = -temp;
		} */
		for(; a_left<=a_right; ++a_left)
		{
			val = ABS(a_left) - start_offset;
			aa = val/3;
			if(aa < 0 || aa > end_pos)/*stop & partial codon*/
			{
				buf[p_pos] = '^';
			}
			else
			{
				if(val%3==1)/*label aa in the middle of 3-bp codon*/
				{
					if(start_pos == -1)
						start_pos = aa;
					if(spp !=NULL)
					{
						SeqPortSeek(spp, aa, SEEK_SET);
						residue = SeqPortGetResidue(spp); 
					}
					else
					{
						BSSeek(p_data, aa, SEEK_SET);
						residue = (Uint1)BSGetByte(p_data);
					}
					if(IS_ALPHA(residue) || residue == '*' || residue == '-')
					
						buf[p_pos] = residue;
					else
						buf[p_pos] = '?';
				}
				else
					buf[p_pos] = ' ';
			}
			if(reverse_order)
				-- p_pos;
			else {
				++p_pos;
                                if (p_pos > buf_len)
                                   break;
                        }
		}
	     }
	     cd_len += SeqLocLen(slp);
	     /*frame_offset = (cd_len - start_offset)%3;
	     if(frame_offset > 0)
		--frame_offset;*/
		
	}

	if(spp != NULL)
		SeqPortFree(spp);
	if(p_data != NULL)
		BSFree(p_data);

	if(p_pos  == 0)	/*all the residues are introns*/
	{
		if(seal_ends)
		{
			end_pos = buf_len;
			MemSet((Pointer)buf, '~', (size_t)(end_pos) * sizeof(Char));
			buf[end_pos] = '\0';
		}
	}
	else
	{
		if(seal_ends)
		{
			buf[p_pos] = '\0';
		}
		if(start_pos == -1)
			start_pos = aa;
	}

	return start_pos;
}
Esempio n. 22
0
int cfg_get_token(cfg_token_t* token, cfg_parser_t* st, unsigned int flags)
{
	static int look_ahead = EOF;
	int c;
	enum st state;

	state = ST_S;
	
	token->val.s = token->buf;
	token->val.len = 0;

	if (look_ahead != EOF) {
		c = look_ahead;
		look_ahead = EOF;
	} else {
		READ_CHAR;
	}

	while(c != EOF) {
		switch(state) {
		case ST_S:
			if (flags & CFG_EXTENDED_ALPHA) {
				if (IS_WHITESPACE(c)) {
					     /* Do nothing */
				} else if (IS_ALPHA(c) ||
					   IS_ESCAPE(c) ||
					   IS_DELIM(c)) {
					PUSH(c);
					state = ST_A;
				} else if (IS_QUOTE(c)) {
					state = ST_Q;
				} else if (IS_COMMENT(c)) {
					state = ST_C;
				} else if (IS_EOL(c)) {
					PUSH(c);
					RETURN(c);
				} else {
					ERR("%s:%d:%d: Invalid character 0x%x\n", 
					    st->file, st->line, st->col, c);
					return -1;
				}
			} else {
				if (IS_WHITESPACE(c)) {
					     /* Do nothing */
				} else if (IS_ALPHA(c)) {
					PUSH(c);
					state = ST_A;
				} else if (IS_QUOTE(c)) {
					state = ST_Q;
				} else if (IS_COMMENT(c)) {
					state = ST_C;
				} else if (IS_ESCAPE(c)) {
					state = ST_E;
				} else if (IS_DELIM(c) || IS_EOL(c)) {
					PUSH(c);
					RETURN(c);
				} else {
					ERR("%s:%d:%d: Invalid character 0x%x\n", 
					    st->file, st->line, st->col, c);
					return -1;
				}
			}
			break;

		case ST_A:
			if (flags & CFG_EXTENDED_ALPHA) {
				if (IS_ALPHA(c) ||
				    IS_DELIM(c) ||
				    IS_QUOTE(c)) {
					PUSH(c);
				} else if (IS_ESCAPE(c)) {
					state = ST_AE;
				} else if (IS_COMMENT(c) || IS_EOL(c) || IS_WHITESPACE(c)) {
					look_ahead = c;
					RETURN(CFG_TOKEN_ALPHA);
				} else {
					ERR("%s:%d:%d: Invalid character 0x%x\n", 
					    st->file, st->line, st->col, c);
					return -1;
				}
			} else {
				if (IS_ALPHA(c)) {
					PUSH(c);
				} else if (IS_ESCAPE(c)) {
					state = ST_AE;
				} else if (IS_WHITESPACE(c) ||
					   IS_DELIM(c) ||
					   IS_QUOTE(c) ||
					   IS_COMMENT(c) ||
					   IS_EOL(c)) {
					look_ahead = c;
					RETURN(CFG_TOKEN_ALPHA);
				} else {
					ERR("%s:%d:%d: Invalid character 0x%x\n", 
					    st->file, st->line, st->col, c);
					return -1;
				}
			}
			break;

		case ST_AE:
			if (IS_COMMENT(c) ||
			    IS_QUOTE(c) ||
			    IS_ESCAPE(c)) {
				PUSH(c);
			} else if (c == 'r') {
				PUSH('\r');
			} else if (c == 'n') {
				PUSH('\n');
			} else if (c == 't') {
				PUSH('\t');
			} else if (c == ' ') {
				PUSH(' ');
			} else if (IS_EOL(c)) {
				     /* Do nothing */
			} else {
				ERR("%s:%d:%d: Unsupported escape character 0x%x\n", 
				    st->file, st->line, st->col, c);
				return -1;
			}
			state = ST_A;
			break;

		case ST_Q:
			if (IS_QUOTE(c)) {
				RETURN(CFG_TOKEN_STRING);
			} else if (IS_ESCAPE(c)) {
				state = ST_QE;
				break;
			} else {
				PUSH(c);
			}
			break;

		case ST_QE:
			if (IS_ESCAPE(c) ||
			    IS_QUOTE(c)) {
				PUSH(c);
			} else if (c == 'n') {
				PUSH('\n');
			} else if (c == 'r') {
				PUSH('\r');
			} else if (c == 't') {
				PUSH('\t');
			} else if (IS_EOL(c)) {
				     /* Do nothing */
			} else {
				ERR("%s:%d:%d: Unsupported escape character 0x%x\n", 
				    st->file, st->line, st->col, c);
				return -1;
			}
			state = ST_Q;
			break;

		case ST_C:
			if (IS_ESCAPE(c)) {
				state = ST_CE;
			} else if (IS_EOL(c)) {
				state = ST_S;
				continue; /* Do not read a new char, return EOL */
			} else {
				     /* Do nothing */
			}
			break;

		case ST_CE:
			state = ST_C;
			break;

		case ST_E:
			if (IS_COMMENT(c) ||
			    IS_QUOTE(c) ||
			    IS_ESCAPE(c)) {
				PUSH(c);
				RETURN(c);
			} else if (c == 'r') {
				PUSH('\r');
				RETURN('\r');
			} else if (c == 'n') {
				PUSH('\n');
				RETURN('\n');
			} else if (c == 't') {
				PUSH('\t');
				RETURN('\t');
			} else if (c == ' ') {
				PUSH(' ');
				RETURN(' ');
			} else if (IS_EOL(c)) {
				     /* Escped eol means no eol */
				state = ST_S;
			} else {
				ERR("%s:%d:%d: Unsupported escape character 0x%x\n", 
				    st->file, st->line, st->col, c);
				return -1;
			}
			break;
		}

		READ_CHAR;
	};

	switch(state) {
	case ST_S: 
	case ST_C:
	case ST_CE:
		return 1;

	case ST_A:
		RETURN(CFG_TOKEN_ALPHA);

	case ST_Q:
		ERR("%s:%d:%d: Premature end of file, missing closing quote in"
			" string constant\n", st->file, st->line, st->col);
		return -1;

	case ST_QE:
	case ST_E:
	case ST_AE:
		ERR("%s:%d:%d: Premature end of file, missing escaped character\n", 
		    st->file, st->line, st->col);
		return -1;
	}
	BUG("%s:%d:%d: Invalid state %d\n",
		st->file, st->line, st->col, state);
	return -1;
}
Esempio n. 23
0
size_t http_parser_execute (http_parser *parser,
                            const http_parser_settings *settings,
                            const char *data,
                            size_t len)
{
  char c, ch;
  int8_t unhex_val;
  const char *p = data, *pe;
  int64_t to_read;
  enum state state;
  enum header_states header_state;
  uint64_t index = parser->index;
  uint64_t nread = parser->nread;

  /* We're in an error state. Don't bother doing anything. */
  if (HTTP_PARSER_ERRNO(parser) != HPE_OK) {
    return 0;
  }

  state = (enum state) parser->state;
  header_state = (enum header_states) parser->header_state;

  if (len == 0) {
    switch (state) {
      case s_body_identity_eof:
        CALLBACK2(message_complete);
        return 0;

      case s_dead:
      case s_start_req_or_res:
      case s_start_res:
      case s_start_req:
        return 0;

      default:
        SET_ERRNO(HPE_INVALID_EOF_STATE);
        return 1;
    }
  }

  /* technically we could combine all of these (except for url_mark) into one
     variable, saving stack space, but it seems more clear to have them
     separated. */
  const char *header_field_mark = 0;
  const char *header_value_mark = 0;
  const char *url_mark = 0;

  if (state == s_header_field)
    header_field_mark = data;
  if (state == s_header_value)
    header_value_mark = data;
  if (state == s_req_path || state == s_req_schema || state == s_req_schema_slash
      || state == s_req_schema_slash_slash || state == s_req_port
      || state == s_req_query_string_start || state == s_req_query_string
      || state == s_req_host
      || state == s_req_fragment_start || state == s_req_fragment)
    url_mark = data;

  for (p=data, pe=data+len; p != pe; p++) {
    ch = *p;

    if (PARSING_HEADER(state)) {
      ++nread;
      /* Buffer overflow attack */
      if (nread > HTTP_MAX_HEADER_SIZE) {
        SET_ERRNO(HPE_HEADER_OVERFLOW);
        goto error;
      }
    }

    switch (state) {

      case s_dead:
        /* this state is used after a 'Connection: close' message
         * the parser will error out if it reads another message
         */
        SET_ERRNO(HPE_CLOSED_CONNECTION);
        goto error;

      case s_start_req_or_res:
      {
        if (ch == CR || ch == LF)
          break;
        parser->flags = 0;
        parser->content_length = -1;

        CALLBACK2(message_begin);

        if (ch == 'H')
          state = s_res_or_resp_H;
        else {
          parser->type = HTTP_REQUEST;
          goto start_req_method_assign;
        }
        break;
      }

      case s_res_or_resp_H:
        if (ch == 'T') {
          parser->type = HTTP_RESPONSE;
          state = s_res_HT;
        } else {
          if (ch != 'E') {
            SET_ERRNO(HPE_INVALID_CONSTANT);
            goto error;
          }

          parser->type = HTTP_REQUEST;
          parser->method = HTTP_HEAD;
          index = 2;
          state = s_req_method;
        }
        break;

      case s_start_res:
      {
        parser->flags = 0;
        parser->content_length = -1;

        CALLBACK2(message_begin);

        switch (ch) {
          case 'H':
            state = s_res_H;
            break;

          case CR:
          case LF:
            break;

          default:
            SET_ERRNO(HPE_INVALID_CONSTANT);
            goto error;
        }
        break;
      }

      case s_res_H:
        STRICT_CHECK(ch != 'T');
        state = s_res_HT;
        break;

      case s_res_HT:
        STRICT_CHECK(ch != 'T');
        state = s_res_HTT;
        break;

      case s_res_HTT:
        STRICT_CHECK(ch != 'P');
        state = s_res_HTTP;
        break;

      case s_res_HTTP:
        STRICT_CHECK(ch != '/');
        state = s_res_first_http_major;
        break;

      case s_res_first_http_major:
        if (ch < '1' || ch > '9') {
          SET_ERRNO(HPE_INVALID_VERSION);
          goto error;
        }

        parser->http_major = ch - '0';
        state = s_res_http_major;
        break;

      /* major HTTP version or dot */
      case s_res_http_major:
      {
        if (ch == '.') {
          state = s_res_first_http_minor;
          break;
        }

        if (!IS_NUM(ch)) {
          SET_ERRNO(HPE_INVALID_VERSION);
          goto error;
        }

        parser->http_major *= 10;
        parser->http_major += ch - '0';

        if (parser->http_major > 999) {
          SET_ERRNO(HPE_INVALID_VERSION);
          goto error;
        }

        break;
      }

      /* first digit of minor HTTP version */
      case s_res_first_http_minor:
        if (!IS_NUM(ch)) {
          SET_ERRNO(HPE_INVALID_VERSION);
          goto error;
        }

        parser->http_minor = ch - '0';
        state = s_res_http_minor;
        break;

      /* minor HTTP version or end of request line */
      case s_res_http_minor:
      {
        if (ch == ' ') {
          state = s_res_first_status_code;
          break;
        }

        if (!IS_NUM(ch)) {
          SET_ERRNO(HPE_INVALID_VERSION);
          goto error;
        }

        parser->http_minor *= 10;
        parser->http_minor += ch - '0';

        if (parser->http_minor > 999) {
          SET_ERRNO(HPE_INVALID_VERSION);
          goto error;
        }

        break;
      }

      case s_res_first_status_code:
      {
        if (!IS_NUM(ch)) {
          if (ch == ' ') {
            break;
          }

          SET_ERRNO(HPE_INVALID_STATUS);
          goto error;
        }
        parser->status_code = ch - '0';
        state = s_res_status_code;
        break;
      }

      case s_res_status_code:
      {
        if (!IS_NUM(ch)) {
          switch (ch) {
            case ' ':
              state = s_res_status;
              break;
            case CR:
              state = s_res_line_almost_done;
              break;
            case LF:
              state = s_header_field_start;
              break;
            default:
              SET_ERRNO(HPE_INVALID_STATUS);
              goto error;
          }
          break;
        }

        parser->status_code *= 10;
        parser->status_code += ch - '0';

        if (parser->status_code > 999) {
          SET_ERRNO(HPE_INVALID_STATUS);
          goto error;
        }

        break;
      }

      case s_res_status:
        /* the human readable status. e.g. "NOT FOUND"
         * we are not humans so just ignore this */
        if (ch == CR) {
          state = s_res_line_almost_done;
          break;
        }

        if (ch == LF) {
          state = s_header_field_start;
          break;
        }
        break;

      case s_res_line_almost_done:
        STRICT_CHECK(ch != LF);
        state = s_header_field_start;
        break;

      case s_start_req:
      {
        if (ch == CR || ch == LF)
          break;
        parser->flags = 0;
        parser->content_length = -1;

        CALLBACK2(message_begin);

        if (!IS_ALPHA(ch)) {
          SET_ERRNO(HPE_INVALID_METHOD);
          goto error;
        }

      start_req_method_assign:
        parser->method = (enum http_method) 0;
        index = 1;
        switch (ch) {
          case 'C': parser->method = HTTP_CONNECT; /* or COPY, CHECKOUT */ break;
          case 'D': parser->method = HTTP_DELETE; break;
          case 'G': parser->method = HTTP_GET; break;
          case 'H': parser->method = HTTP_HEAD; break;
          case 'L': parser->method = HTTP_LOCK; break;
          case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH */ break;
          case 'N': parser->method = HTTP_NOTIFY; break;
          case 'O': parser->method = HTTP_OPTIONS; break;
          case 'P': parser->method = HTTP_POST;
            /* or PROPFIND or PROPPATCH or PUT or PATCH */
            break;
          case 'R': parser->method = HTTP_REPORT; break;
          case 'S': parser->method = HTTP_SUBSCRIBE; break;
          case 'T': parser->method = HTTP_TRACE; break;
          case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE */ break;
          default:
            SET_ERRNO(HPE_INVALID_METHOD);
            goto error;
        }
        state = s_req_method;
        break;
      }

      case s_req_method:
      {
        if (ch == '\0') {
          SET_ERRNO(HPE_INVALID_METHOD);
          goto error;
        }

        const char *matcher = method_strings[parser->method];
        if (ch == ' ' && matcher[index] == '\0') {
          state = s_req_spaces_before_url;
        } else if (ch == matcher[index]) {
          ; /* nada */
        } else if (parser->method == HTTP_CONNECT) {
          if (index == 1 && ch == 'H') {
            parser->method = HTTP_CHECKOUT;
          } else if (index == 2  && ch == 'P') {
            parser->method = HTTP_COPY;
          } else {
            goto error;
          }
        } else if (parser->method == HTTP_MKCOL) {
          if (index == 1 && ch == 'O') {
            parser->method = HTTP_MOVE;
          } else if (index == 1 && ch == 'E') {
            parser->method = HTTP_MERGE;
          } else if (index == 1 && ch == '-') {
            parser->method = HTTP_MSEARCH;
          } else if (index == 2 && ch == 'A') {
            parser->method = HTTP_MKACTIVITY;
          } else {
            goto error;
          }
        } else if (index == 1 && parser->method == HTTP_POST) {
          if (ch == 'R') {
            parser->method = HTTP_PROPFIND; /* or HTTP_PROPPATCH */
          } else if (ch == 'U') {
            parser->method = HTTP_PUT;
          } else if (ch == 'A') {
            parser->method = HTTP_PATCH;
          } else {
            goto error;
          }
        } else if (index == 2 && parser->method == HTTP_UNLOCK && ch == 'S') {
          parser->method = HTTP_UNSUBSCRIBE;
        } else if (index == 4 && parser->method == HTTP_PROPFIND && ch == 'P') {
          parser->method = HTTP_PROPPATCH;
        } else {
          SET_ERRNO(HPE_INVALID_METHOD);
          goto error;
        }

        ++index;
        break;
      }
      case s_req_spaces_before_url:
      {
        if (ch == ' ') break;

        if (ch == '/' || ch == '*') {
          MARK(url);
          state = s_req_path;
          break;
        }

        /* Proxied requests are followed by scheme of an absolute URI (alpha).
         * CONNECT is followed by a hostname, which begins with alphanum.
         * All other methods are followed by '/' or '*' (handled above).
         */
        if (IS_ALPHA(ch) || (parser->method == HTTP_CONNECT && IS_NUM(ch))) {
          MARK(url);
          state = (parser->method == HTTP_CONNECT) ? s_req_host : s_req_schema;
          break;
        }

        SET_ERRNO(HPE_INVALID_URL);
        goto error;
      }

      case s_req_schema:
      {
        if (IS_ALPHA(ch)) break;

        if (ch == ':') {
          state = s_req_schema_slash;
          break;
        }

        SET_ERRNO(HPE_INVALID_URL);
        goto error;
      }

      case s_req_schema_slash:
        STRICT_CHECK(ch != '/');
        state = s_req_schema_slash_slash;
        break;

      case s_req_schema_slash_slash:
        STRICT_CHECK(ch != '/');
        state = s_req_host;
        break;

      case s_req_host:
      {
        if (IS_HOST_CHAR(ch)) break;
        switch (ch) {
          case ':':
            state = s_req_port;
            break;
          case '/':
            state = s_req_path;
            break;
          case ' ':
            /* The request line looks like:
             *   "GET http://foo.bar.com HTTP/1.1"
             * That is, there is no path.
             */
            CALLBACK(url);
            state = s_req_http_start;
            break;
          case '?':
            state = s_req_query_string_start;
            break;
          default:
            SET_ERRNO(HPE_INVALID_HOST);
            goto error;
        }
        break;
      }

      case s_req_port:
      {
        if (IS_NUM(ch)) break;
        switch (ch) {
          case '/':
            state = s_req_path;
            break;
          case ' ':
            /* The request line looks like:
             *   "GET http://foo.bar.com:1234 HTTP/1.1"
             * That is, there is no path.
             */
            CALLBACK(url);
            state = s_req_http_start;
            break;
          case '?':
            state = s_req_query_string_start;
            break;
          default:
            SET_ERRNO(HPE_INVALID_PORT);
            goto error;
        }
        break;
      }

      case s_req_path:
      {
        if (IS_URL_CHAR(ch)) break;

        switch (ch) {
          case ' ':
            CALLBACK(url);
            state = s_req_http_start;
            break;
          case CR:
            CALLBACK(url);
            parser->http_major = 0;
            parser->http_minor = 9;
            state = s_req_line_almost_done;
            break;
          case LF:
            CALLBACK(url);
            parser->http_major = 0;
            parser->http_minor = 9;
            state = s_header_field_start;
            break;
          case '?':
            state = s_req_query_string_start;
            break;
          case '#':
            state = s_req_fragment_start;
            break;
          default:
            SET_ERRNO(HPE_INVALID_PATH);
            goto error;
        }
        break;
      }

      case s_req_query_string_start:
      {
        if (IS_URL_CHAR(ch)) {
          state = s_req_query_string;
          break;
        }

        switch (ch) {
          case '?':
            break; /* XXX ignore extra '?' ... is this right? */
          case ' ':
            CALLBACK(url);
            state = s_req_http_start;
            break;
          case CR:
            CALLBACK(url);
            parser->http_major = 0;
            parser->http_minor = 9;
            state = s_req_line_almost_done;
            break;
          case LF:
            CALLBACK(url);
            parser->http_major = 0;
            parser->http_minor = 9;
            state = s_header_field_start;
            break;
          case '#':
            state = s_req_fragment_start;
            break;
          default:
            SET_ERRNO(HPE_INVALID_QUERY_STRING);
            goto error;
        }
        break;
      }

      case s_req_query_string:
      {
        if (IS_URL_CHAR(ch)) break;

        switch (ch) {
          case '?':
            /* allow extra '?' in query string */
            break;
          case ' ':
            CALLBACK(url);
            state = s_req_http_start;
            break;
          case CR:
            CALLBACK(url);
            parser->http_major = 0;
            parser->http_minor = 9;
            state = s_req_line_almost_done;
            break;
          case LF:
            CALLBACK(url);
            parser->http_major = 0;
            parser->http_minor = 9;
            state = s_header_field_start;
            break;
          case '#':
            state = s_req_fragment_start;
            break;
          default:
            SET_ERRNO(HPE_INVALID_QUERY_STRING);
            goto error;
        }
        break;
      }

      case s_req_fragment_start:
      {
        if (IS_URL_CHAR(ch)) {
          state = s_req_fragment;
          break;
        }

        switch (ch) {
          case ' ':
            CALLBACK(url);
            state = s_req_http_start;
            break;
          case CR:
            CALLBACK(url);
            parser->http_major = 0;
            parser->http_minor = 9;
            state = s_req_line_almost_done;
            break;
          case LF:
            CALLBACK(url);
            parser->http_major = 0;
            parser->http_minor = 9;
            state = s_header_field_start;
            break;
          case '?':
            state = s_req_fragment;
            break;
          case '#':
            break;
          default:
            SET_ERRNO(HPE_INVALID_FRAGMENT);
            goto error;
        }
        break;
      }

      case s_req_fragment:
      {
        if (IS_URL_CHAR(ch)) break;

        switch (ch) {
          case ' ':
            CALLBACK(url);
            state = s_req_http_start;
            break;
          case CR:
            CALLBACK(url);
            parser->http_major = 0;
            parser->http_minor = 9;
            state = s_req_line_almost_done;
            break;
          case LF:
            CALLBACK(url);
            parser->http_major = 0;
            parser->http_minor = 9;
            state = s_header_field_start;
            break;
          case '?':
          case '#':
            break;
          default:
            SET_ERRNO(HPE_INVALID_FRAGMENT);
            goto error;
        }
        break;
      }

      case s_req_http_start:
        switch (ch) {
          case 'H':
            state = s_req_http_H;
            break;
          case ' ':
            break;
          default:
            SET_ERRNO(HPE_INVALID_CONSTANT);
            goto error;
        }
        break;

      case s_req_http_H:
        STRICT_CHECK(ch != 'T');
        state = s_req_http_HT;
        break;

      case s_req_http_HT:
        STRICT_CHECK(ch != 'T');
        state = s_req_http_HTT;
        break;

      case s_req_http_HTT:
        STRICT_CHECK(ch != 'P');
        state = s_req_http_HTTP;
        break;

      case s_req_http_HTTP:
        STRICT_CHECK(ch != '/');
        state = s_req_first_http_major;
        break;

      /* first digit of major HTTP version */
      case s_req_first_http_major:
        if (ch < '1' || ch > '9') {
          SET_ERRNO(HPE_INVALID_VERSION);
          goto error;
        }

        parser->http_major = ch - '0';
        state = s_req_http_major;
        break;

      /* major HTTP version or dot */
      case s_req_http_major:
      {
        if (ch == '.') {
          state = s_req_first_http_minor;
          break;
        }

        if (!IS_NUM(ch)) {
          SET_ERRNO(HPE_INVALID_VERSION);
          goto error;
        }

        parser->http_major *= 10;
        parser->http_major += ch - '0';

        if (parser->http_major > 999) {
          SET_ERRNO(HPE_INVALID_VERSION);
          goto error;
        }

        break;
      }

      /* first digit of minor HTTP version */
      case s_req_first_http_minor:
        if (!IS_NUM(ch)) {
          SET_ERRNO(HPE_INVALID_VERSION);
          goto error;
        }

        parser->http_minor = ch - '0';
        state = s_req_http_minor;
        break;

      /* minor HTTP version or end of request line */
      case s_req_http_minor:
      {
        if (ch == CR) {
          state = s_req_line_almost_done;
          break;
        }

        if (ch == LF) {
          state = s_header_field_start;
          break;
        }

        /* XXX allow spaces after digit? */

        if (!IS_NUM(ch)) {
          SET_ERRNO(HPE_INVALID_VERSION);
          goto error;
        }

        parser->http_minor *= 10;
        parser->http_minor += ch - '0';

        if (parser->http_minor > 999) {
          SET_ERRNO(HPE_INVALID_VERSION);
          goto error;
        }

        break;
      }

      /* end of request line */
      case s_req_line_almost_done:
      {
        if (ch != LF) {
          SET_ERRNO(HPE_LF_EXPECTED);
          goto error;
        }

        state = s_header_field_start;
        break;
      }

      case s_header_field_start:
      header_field_start:
      {
        if (ch == CR) {
          state = s_headers_almost_done;
          break;
        }

        if (ch == LF) {
          /* they might be just sending \n instead of \r\n so this would be
           * the second \n to denote the end of headers*/
          state = s_headers_almost_done;
          goto headers_almost_done;
        }

        c = TOKEN(ch);

        if (!c) {
          SET_ERRNO(HPE_INVALID_HEADER_TOKEN);
          goto error;
        }

        MARK(header_field);

        index = 0;
        state = s_header_field;

        switch (c) {
          case 'c':
            header_state = h_C;
            break;

          case 'p':
            header_state = h_matching_proxy_connection;
            break;

          case 't':
            header_state = h_matching_transfer_encoding;
            break;

          case 'u':
            header_state = h_matching_upgrade;
            break;

          default:
            header_state = h_general;
            break;
        }
        break;
      }

      case s_header_field:
      {
        c = TOKEN(ch);

        if (c) {
          switch (header_state) {
            case h_general:
              break;

            case h_C:
              index++;
              header_state = (c == 'o' ? h_CO : h_general);
              break;

            case h_CO:
              index++;
              header_state = (c == 'n' ? h_CON : h_general);
              break;

            case h_CON:
              index++;
              switch (c) {
                case 'n':
                  header_state = h_matching_connection;
                  break;
                case 't':
                  header_state = h_matching_content_length;
                  break;
                default:
                  header_state = h_general;
                  break;
              }
              break;

            /* connection */

            case h_matching_connection:
              index++;
              if (index > sizeof(CONNECTION)-1
                  || c != CONNECTION[index]) {
                header_state = h_general;
              } else if (index == sizeof(CONNECTION)-2) {
                header_state = h_connection;
              }
              break;

            /* proxy-connection */

            case h_matching_proxy_connection:
              index++;
              if (index > sizeof(PROXY_CONNECTION)-1
                  || c != PROXY_CONNECTION[index]) {
                header_state = h_general;
              } else if (index == sizeof(PROXY_CONNECTION)-2) {
                header_state = h_connection;
              }
              break;

            /* content-length */

            case h_matching_content_length:
              index++;
              if (index > sizeof(CONTENT_LENGTH)-1
                  || c != CONTENT_LENGTH[index]) {
                header_state = h_general;
              } else if (index == sizeof(CONTENT_LENGTH)-2) {
                header_state = h_content_length;
              }
              break;

            /* transfer-encoding */

            case h_matching_transfer_encoding:
              index++;
              if (index > sizeof(TRANSFER_ENCODING)-1
                  || c != TRANSFER_ENCODING[index]) {
                header_state = h_general;
              } else if (index == sizeof(TRANSFER_ENCODING)-2) {
                header_state = h_transfer_encoding;
              }
              break;

            /* upgrade */

            case h_matching_upgrade:
              index++;
              if (index > sizeof(UPGRADE)-1
                  || c != UPGRADE[index]) {
                header_state = h_general;
              } else if (index == sizeof(UPGRADE)-2) {
                header_state = h_upgrade;
              }
              break;

            case h_connection:
            case h_content_length:
            case h_transfer_encoding:
            case h_upgrade:
              if (ch != ' ') header_state = h_general;
              break;

            default:
              assert(0 && "Unknown header_state");
              break;
          }
          break;
        }

        if (ch == ':') {
          CALLBACK(header_field);
          state = s_header_value_start;
          break;
        }

        if (ch == CR) {
          state = s_header_almost_done;
          CALLBACK(header_field);
          break;
        }

        if (ch == LF) {
          CALLBACK(header_field);
          state = s_header_field_start;
          break;
        }

        SET_ERRNO(HPE_INVALID_HEADER_TOKEN);
        goto error;
      }

      case s_header_value_start:
      {
        if (ch == ' ' || ch == '\t') break;

        MARK(header_value);

        state = s_header_value;
        index = 0;

        if (ch == CR) {
          CALLBACK(header_value);
          header_state = h_general;
          state = s_header_almost_done;
          break;
        }

        if (ch == LF) {
          CALLBACK(header_value);
          state = s_header_field_start;
          break;
        }

        c = LOWER(ch);

        switch (header_state) {
          case h_upgrade:
            parser->flags |= F_UPGRADE;
            header_state = h_general;
            break;

          case h_transfer_encoding:
            /* looking for 'Transfer-Encoding: chunked' */
            if ('c' == c) {
              header_state = h_matching_transfer_encoding_chunked;
            } else {
              header_state = h_general;
            }
            break;

          case h_content_length:
            if (!IS_NUM(ch)) {
              SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
              goto error;
            }

            parser->content_length = ch - '0';
            break;

          case h_connection:
            /* looking for 'Connection: keep-alive' */
            if (c == 'k') {
              header_state = h_matching_connection_keep_alive;
            /* looking for 'Connection: close' */
            } else if (c == 'c') {
              header_state = h_matching_connection_close;
            } else {
              header_state = h_general;
            }
            break;

          default:
            header_state = h_general;
            break;
        }
        break;
      }

      case s_header_value:
      {

        if (ch == CR) {
          CALLBACK(header_value);
          state = s_header_almost_done;
          break;
        }

        if (ch == LF) {
          CALLBACK(header_value);
          goto header_almost_done;
        }

        c = LOWER(ch);

        switch (header_state) {
          case h_general:
            break;

          case h_connection:
          case h_transfer_encoding:
            assert(0 && "Shouldn't get here.");
            break;

          case h_content_length:
            if (ch == ' ') break;
            if (!IS_NUM(ch)) {
              SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
              goto error;
            }

            parser->content_length *= 10;
            parser->content_length += ch - '0';
            break;

          /* Transfer-Encoding: chunked */
          case h_matching_transfer_encoding_chunked:
            index++;
            if (index > sizeof(CHUNKED)-1
                || c != CHUNKED[index]) {
              header_state = h_general;
            } else if (index == sizeof(CHUNKED)-2) {
              header_state = h_transfer_encoding_chunked;
            }
            break;

          /* looking for 'Connection: keep-alive' */
          case h_matching_connection_keep_alive:
            index++;
            if (index > sizeof(KEEP_ALIVE)-1
                || c != KEEP_ALIVE[index]) {
              header_state = h_general;
            } else if (index == sizeof(KEEP_ALIVE)-2) {
              header_state = h_connection_keep_alive;
            }
            break;

          /* looking for 'Connection: close' */
          case h_matching_connection_close:
            index++;
            if (index > sizeof(CLOSE)-1 || c != CLOSE[index]) {
              header_state = h_general;
            } else if (index == sizeof(CLOSE)-2) {
              header_state = h_connection_close;
            }
            break;

          case h_transfer_encoding_chunked:
          case h_connection_keep_alive:
          case h_connection_close:
            if (ch != ' ') header_state = h_general;
            break;

          default:
            state = s_header_value;
            header_state = h_general;
            break;
        }
        break;
      }

      case s_header_almost_done:
      header_almost_done:
      {
        STRICT_CHECK(ch != LF);

        state = s_header_value_lws;

        switch (header_state) {
          case h_connection_keep_alive:
            parser->flags |= F_CONNECTION_KEEP_ALIVE;
            break;
          case h_connection_close:
            parser->flags |= F_CONNECTION_CLOSE;
            break;
          case h_transfer_encoding_chunked:
            parser->flags |= F_CHUNKED;
            break;
          default:
            break;
        }
        break;
      }

      case s_header_value_lws:
      {
        if (ch == ' ' || ch == '\t')
          state = s_header_value_start;
        else
        {
          state = s_header_field_start;
          goto header_field_start;
        }
        break;
      }

      case s_headers_almost_done:
      headers_almost_done:
      {
        STRICT_CHECK(ch != LF);

        if (parser->flags & F_TRAILING) {
          /* End of a chunked request */
          CALLBACK2(message_complete);
          state = NEW_MESSAGE();
          break;
        }

        nread = 0;

        if (parser->flags & F_UPGRADE || parser->method == HTTP_CONNECT) {
          parser->upgrade = 1;
        }

        /* Here we call the headers_complete callback. This is somewhat
         * different than other callbacks because if the user returns 1, we
         * will interpret that as saying that this message has no body. This
         * is needed for the annoying case of recieving a response to a HEAD
         * request.
         */
        if (settings->on_headers_complete) {
          switch (settings->on_headers_complete(parser)) {
            case 0:
              break;

            case 1:
              parser->flags |= F_SKIPBODY;
              break;

            default:
              parser->state = state;
              SET_ERRNO(HPE_CB_headers_complete);
              return p - data; /* Error */
          }
        }

        /* Exit, the rest of the connect is in a different protocol. */
        if (parser->upgrade) {
          CALLBACK2(message_complete);
          return (p - data) + 1;
        }

        if (parser->flags & F_SKIPBODY) {
          CALLBACK2(message_complete);
          state = NEW_MESSAGE();
        } else if (parser->flags & F_CHUNKED) {
          /* chunked encoding - ignore Content-Length header */
          state = s_chunk_size_start;
        } else {
          if (parser->content_length == 0) {
            /* Content-Length header given but zero: Content-Length: 0\r\n */
            CALLBACK2(message_complete);
            state = NEW_MESSAGE();
          } else if (parser->content_length > 0) {
            /* Content-Length header given and non-zero */
            state = s_body_identity;
          } else {
            if (parser->type == HTTP_REQUEST || http_should_keep_alive(parser)) {
              /* Assume content-length 0 - read the next */
              CALLBACK2(message_complete);
              state = NEW_MESSAGE();
            } else {
              /* Read body until EOF */
              state = s_body_identity_eof;
            }
          }
        }

        break;
      }

      case s_body_identity:
        to_read = MIN(pe - p, (int64_t)parser->content_length);
        if (to_read > 0) {
          if (settings->on_body) settings->on_body(parser, p, to_read);
          p += to_read - 1;
          parser->content_length -= to_read;
          if (parser->content_length == 0) {
            CALLBACK2(message_complete);
            state = NEW_MESSAGE();
          }
        }
        break;

      /* read until EOF */
      case s_body_identity_eof:
        to_read = pe - p;
        if (to_read > 0) {
          if (settings->on_body) settings->on_body(parser, p, to_read);
          p += to_read - 1;
        }
        break;

      case s_chunk_size_start:
      {
        assert(nread == 1);
        assert(parser->flags & F_CHUNKED);

        unhex_val = unhex[(unsigned char)ch];
        if (unhex_val == -1) {
          SET_ERRNO(HPE_INVALID_CHUNK_SIZE);
          goto error;
        }

        parser->content_length = unhex_val;
        state = s_chunk_size;
        break;
      }

      case s_chunk_size:
      {
        assert(parser->flags & F_CHUNKED);

        if (ch == CR) {
          state = s_chunk_size_almost_done;
          break;
        }

        unhex_val = unhex[(unsigned char)ch];

        if (unhex_val == -1) {
          if (ch == ';' || ch == ' ') {
            state = s_chunk_parameters;
            break;
          }

          SET_ERRNO(HPE_INVALID_CHUNK_SIZE);
          goto error;
        }

        parser->content_length *= 16;
        parser->content_length += unhex_val;
        break;
      }

      case s_chunk_parameters:
      {
        assert(parser->flags & F_CHUNKED);
        /* just ignore this shit. TODO check for overflow */
        if (ch == CR) {
          state = s_chunk_size_almost_done;
          break;
        }
        break;
      }

      case s_chunk_size_almost_done:
      {
        assert(parser->flags & F_CHUNKED);
        STRICT_CHECK(ch != LF);

        nread = 0;

        if (parser->content_length == 0) {
          parser->flags |= F_TRAILING;
          state = s_header_field_start;
        } else {
          state = s_chunk_data;
        }
        break;
      }

      case s_chunk_data:
      {
        assert(parser->flags & F_CHUNKED);

        to_read = MIN(pe - p, (int64_t)(parser->content_length));

        if (to_read > 0) {
          if (settings->on_body) settings->on_body(parser, p, to_read);
          p += to_read - 1;
        }

        if (to_read == parser->content_length) {
          state = s_chunk_data_almost_done;
        }

        parser->content_length -= to_read;
        break;
      }

      case s_chunk_data_almost_done:
        assert(parser->flags & F_CHUNKED);
        STRICT_CHECK(ch != CR);
        state = s_chunk_data_done;
        break;

      case s_chunk_data_done:
        assert(parser->flags & F_CHUNKED);
        STRICT_CHECK(ch != LF);
        state = s_chunk_size_start;
        break;

      default:
        assert(0 && "unhandled state");
        SET_ERRNO(HPE_INVALID_INTERNAL_STATE);
        goto error;
    }
  }

  CALLBACK(header_field);
  CALLBACK(header_value);
  CALLBACK(url);

  parser->state = state;
  parser->header_state = header_state;
  parser->index = index;
  parser->nread = nread;

  return len;

error:
  if (HTTP_PARSER_ERRNO(parser) == HPE_OK) {
    SET_ERRNO(HPE_UNKNOWN);
  }

  return (p - data);
}
Esempio n. 24
0
int webc_font_family_index (
		const WEBC_CHAR* name,
		const WEBC_CHAR* genericName,
		const WEBC_CHAR** fontNames,
		const WEBC_CHAR** fontGenericNames,
		int numFonts
	)
{
	if (!name)
	{
		name = genericName;
		genericName = 0;
	}

	while (name)
	{
		const WEBC_CHAR* pos = name;
		const WEBC_CHAR* last;
		WEBC_CHAR quoteChar;

		while (*pos)
		{
			while (*pos && !IS_ALPHA(*pos) && *pos != '\'' && *pos != '\"')
			{
				pos++;
			}

			if (!*pos)
			{
				break;
			}

			if (*pos == '\'' || *pos == '\"')
			{
				quoteChar = *pos;
				pos++;
			}
			else
			{
				quoteChar = 0;
			}

			last = pos;
			while (*last && (quoteChar || (!IS_WHITESPACE(*last) && *last != ',')) && (!quoteChar || *last != quoteChar))
			{
				last++;
			}

			if (!*last)
			{
				int n;

				for (n=0; n<numFonts; n++)
				{
					if (fontNames[n])
					{
						if (!webc_stricmp(fontNames[n], pos) ||
							(fontGenericNames[n] && !webc_stricmp(fontGenericNames[n], pos)))
						{
							return (n);
						}
					}
				}
			}
			else
			{
				int len = last - pos;
				int n;

				for (n=0; n<numFonts; n++)
				{
					if (fontNames[n])
					{
						if (!webc_strnicmp(fontNames[n], pos, len) ||
							(fontGenericNames[n] && !webc_strnicmp(fontGenericNames[n], pos, len)))
						{
							return (n);
						}
					}
				}
			}

			if (quoteChar && *last == quoteChar)
			{
				last++;
			}

			pos = last;
		}

		name = genericName;
		genericName = 0;
	}

	return (-1);
}
Esempio n. 25
0
Str
Sprintf(char *fmt, ...)
{
    int len = 0;
    int status = SP_NORMAL;
    int p = 0;
    char *f;
    Str s;
    va_list ap;

    va_start(ap, fmt);
    for (f = fmt; *f; f++) {
      redo:
	switch (status) {
	case SP_NORMAL:
	    if (*f == '%') {
		status = SP_PREC;
		p = 0;
	    }
	    else
		len++;
	    break;
	case SP_PREC:
	    if (IS_ALPHA(*f)) {
		/* conversion char. */
		double vd;
		int vi;
		char *vs;
		void *vp;

		switch (*f) {
		case 'l':
		case 'h':
		case 'L':
		case 'w':
		    continue;
		case 'd':
		case 'i':
		case 'o':
		case 'x':
		case 'X':
		case 'u':
		    vi = va_arg(ap, int);
		    len += (p > 0) ? p : 10;
		    break;
		case 'f':
		case 'g':
		case 'e':
		case 'G':
		case 'E':
		    vd = va_arg(ap, double);
		    len += (p > 0) ? p : 15;
		    break;
		case 'c':
		    len += 1;
		    vi = va_arg(ap, int);
		    break;
		case 's':
		    vs = va_arg(ap, char *);
		    vi = strlen(vs);
		    len += (p > vi) ? p : vi;
		    break;
		case 'p':
		    vp = va_arg(ap, void *);
		    len += 10;
		    break;
		case 'n':
		    vp = va_arg(ap, void *);
		    break;
		}
		status = SP_NORMAL;
	    }
	    else if (IS_DIGIT(*f))
		p = p * 10 + *f - '0';
	    else if (*f == '.')
		status = SP_PREC2;
	    else if (*f == '%') {
		status = SP_NORMAL;
		len++;
	    }
	    break;
	case SP_PREC2:
	    if (IS_ALPHA(*f)) {
		status = SP_PREC;
		goto redo;
	    }
	    break;
	}
Esempio n. 26
0
static Str
unquote_mailcap_loop(char *qstr, char *type, char *name, char *attr,
		     int *mc_stat, int flag0)
{
    Str str, tmp, test, then;
    char *p;
    int status = MC_NORMAL, prev_status = MC_NORMAL, sp = 0, flag;

    if (mc_stat)
	*mc_stat = 0;

    if (qstr == NULL)
	return NULL;

    str = Strnew();
    tmp = test = then = NULL;

    for (flag = flag0, p = qstr; *p; p++) {
	if (status == MC_QUOTED) {
	    if (prev_status == MC_PREC2)
		Strcat_char(tmp, *p);
	    else
		Strcat_char(str, *p);
	    status = prev_status;
	    continue;
	}
	else if (*p == '\\') {
	    prev_status = status;
	    status = MC_QUOTED;
	    continue;
	}
	switch (status) {
	case MC_NORMAL:
	    if (*p == '%') {
		status = MC_PREC;
	    }
	    else {
		if (*p == '\'') {
		    if (!flag0 && flag & MCF_SQUOTED)
			flag &= ~MCF_SQUOTED;
		    else if (!flag)
			flag |= MCF_SQUOTED;
		}
		else if (*p == '"') {
		    if (!flag0 && flag & MCF_DQUOTED)
			flag &= ~MCF_DQUOTED;
		    else if (!flag)
			flag |= MCF_DQUOTED;
		}
		Strcat_char(str, *p);
	    }
	    break;
	case MC_PREC:
	    if (IS_ALPHA(*p)) {
		switch (*p) {
		case 's':
		    if (name) {
			Strcat_charp(str, quote_mailcap(name, flag)->ptr);
			if (mc_stat)
			    *mc_stat |= MCSTAT_REPNAME;
		    }
		    break;
		case 't':
		    if (type) {
			Strcat_charp(str, quote_mailcap(type, flag)->ptr);
			if (mc_stat)
			    *mc_stat |= MCSTAT_REPTYPE;
		    }
		    break;
		}
		status = MC_NORMAL;
	    }
	    else if (*p == '{') {
		status = MC_PREC2;
		test = then = NULL;
		tmp = Strnew();
	    }
	    else if (*p == '%') {
		Strcat_char(str, *p);
	    }
	    break;
	case MC_PREC2:
	    if (sp > 0 || *p == '{') {
		Strcat_char(tmp, *p);

		switch (*p) {
		case '{':
		    ++sp;
		    break;
		case '}':
		    --sp;
		    break;
		default:
		    break;
		}
	    }
	    else if (*p == '}') {
		char *q;
		if (attr && (q = strcasestr(attr, tmp->ptr)) != NULL &&
		    (q == attr || IS_SPACE(*(q - 1)) || *(q - 1) == ';') &&
		    matchattr(q, tmp->ptr, tmp->length, &tmp)) {
		    Strcat_charp(str, quote_mailcap(tmp->ptr, flag)->ptr);
		    if (mc_stat)
			*mc_stat |= MCSTAT_REPPARAM;
		}
		status = MC_NORMAL;
	    }
	    else {
		Strcat_char(tmp, *p);
	    }
	    break;
	}
    }
    return str;
}
Esempio n. 27
0
int configuration_load (configuration_t *conf, const char *filename)
{
	FILE *file;
	char buffer[20 * 1024];
	char *ptr, *ptrEnd;
	off_t state = 0;
	size_t bytes;
	char key_name[CONF_KEY_NAME_MAXLEN + 1];
	char value[CONF_VALUE_MAXLEN + 1];
	off_t nline = 1;
	size_t len;
	char c;
	conf_key_t *key = NULL;
	conf_key_list_t *current_list = NULL, *parent_list = NULL;

	configuration_free (conf);

	/* Open file for reading. */
	file = fopen (filename, "rb");
	if (!file) {
		fprintf (stderr, "Couldn't open [%s] for reading.\n", filename);
		return -1;
	}

	current_list = &conf->root;
	len = 0;

	do {
		bytes = fread (buffer, 1, sizeof (buffer), file);
		if (bytes <= 0) {
			*buffer = '\n';
			ptrEnd = buffer + 1;
		} else {
			ptrEnd = buffer + bytes;
		}

		ptr = buffer;

		while (ptr < ptrEnd) {
			switch (state) {
				case 0:
					/* No keys/values found yet. */
					if (*ptr == '{') {
						if ((!key) || (!current_list)) {
							/* No parent key present. */
							fprintf (stderr, "[%s:%lu] No parent key present.\n", filename, nline);
							fclose (file);
							return -1;
						}

						parent_list = current_list;
						current_list = NULL;
					} else if (*ptr == '}') {
						if (!parent_list) {
							/* No parent list present. */
							fprintf (stderr, "[%s:%lu] No parent list present.\n", filename, nline);
							fclose (file);
							return -1;
						}

						current_list = parent_list;
						parent_list = current_list->parent;
						key = NULL;
					} else if (*ptr == COMMENT) {
						state = 8;
					} else if (*ptr == '\n') {
						nline++;
					} else if ((IS_ALPHA (*ptr)) || (IS_DIGIT (*ptr)) || (strchr (SAFE, *ptr))) {
						if (current_list) {
							key = NULL;
						}

						*key_name = *ptr;
						len = 1;

						state = 1;
					} else if ((*ptr != '\r') && (*ptr != ' ') && (*ptr != '\t')) {
						/* Wrong character. */
						fprintf (stderr, "[%s:%lu] Wrong character found: [%c].\n", filename, nline, *ptr);
						fclose (file);
						return -1;
					}

					break;
				case 1:
					/* Reading key. */
					if ((IS_ALPHA (*ptr)) || (IS_DIGIT (*ptr)) || (strchr (SAFE, *ptr))) {
						if (len >= CONF_KEY_NAME_MAXLEN) {
							/* Key name too long. */
							fprintf (stderr, "[%s:%lu] Key name too long (> %d).\n", filename, nline, CONF_KEY_NAME_MAXLEN);
							fclose (file);
							return -1;
						}

						key_name[len++] = *ptr;
					} else if ((*ptr == '\r') || (*ptr == ' ') || (*ptr == '\t')) {
						key_name[len] = 0;
						if ((key = add_key (conf, parent_list, key, &current_list, key_name, len)) == NULL) {
							/* Couldn't allocate memory. */
							fprintf (stderr, "[%s:%lu] Couldn't allocate memory.\n", filename, nline);
							fclose (file);
							return -1;
						}

						state = 2;
					} else if (*ptr == '\n') {
						key_name[len] = 0;
						if ((key = add_key (conf, parent_list, key, &current_list, key_name, len)) == NULL) {
							/* Couldn't allocate memory. */
							fprintf (stderr, "[%s:%lu] Couldn't allocate memory.\n", filename, nline);
							fclose (file);
							return -1;
						}

						key->type = KEY_MIGHT_HAVE_CHILDREN;

						nline++;

						state = 0;
					} else if (*ptr == '=') {
						key_name[len] = 0;
						if ((key = add_key (conf, parent_list, key, &current_list, key_name, len)) == NULL) {
							/* Couldn't allocate memory. */
							fprintf (stderr, "[%s:%lu] Couldn't allocate memory.\n", filename, nline);
							fclose (file);
							return -1;
						}

						state = 3;
					} else if (*ptr == '{') {
						key_name[len] = 0;
						if ((key = add_key (conf, parent_list, key, &current_list, key_name, len)) == NULL) {
							/* Couldn't allocate memory. */
							fprintf (stderr, "[%s:%lu] Couldn't allocate memory.\n", filename, nline);
							fclose (file);
							return -1;
						}

						key->type = KEY_MIGHT_HAVE_CHILDREN;

						parent_list = current_list;
						current_list = NULL;

						state = 0;
					} else if (*ptr == '}') {
						if (!parent_list) {
							/* No parent list present. */
							fprintf (stderr, "[%s:%lu] No parent list present.\n", filename, nline);
							fclose (file);
							return -1;
						}

						key_name[len] = 0;
						if ((key = add_key (conf, parent_list, key, &current_list, key_name, len)) == NULL) {
							/* Couldn't allocate memory. */
							fprintf (stderr, "[%s:%lu] Couldn't allocate memory.\n", filename, nline);
							fclose (file);
							return -1;
						}

						key->type = KEY_MIGHT_HAVE_CHILDREN;

						current_list = parent_list;
						parent_list = current_list->parent;
						key = NULL;

						state = 0;
					} else {
						/* Wrong character. */
						fprintf (stderr, "[%s:%lu] Wrong character found: [%c].\n", filename, nline, *ptr);
						fclose (file);
						return -1;
					}

					break;
				case 2:
					/* Space after key. */
					if (*ptr == '\n') {
						key->type = KEY_MIGHT_HAVE_CHILDREN;

						nline++;

						state = 0;
					} else if (*ptr == COMMENT) {
						key->type = KEY_MIGHT_HAVE_CHILDREN;

						state = 8;
					} else if (*ptr == '=') {
						state = 3;
					} else if (*ptr == '{') {
						key->type = KEY_MIGHT_HAVE_CHILDREN;

						parent_list = current_list;
						current_list = NULL;

						state = 0;
					} else if (*ptr == '}') {
						if (!parent_list) {
							/* No parent list present. */
							fprintf (stderr, "[%s:%lu] No parent list present.\n", filename, nline);
							fclose (file);
							return -1;
						}

						key->type = KEY_MIGHT_HAVE_CHILDREN;

						current_list = parent_list;
						parent_list = current_list->parent;
						key = NULL;

						state = 0;
					} else if ((*ptr != '\r') && (*ptr != ' ') && (*ptr != '\t')) {
						/* Wrong character. */
						fprintf (stderr, "[%s:%lu] Wrong character found: [%c].\n", filename, nline, *ptr);
						fclose (file);
						return -1;
					}

					break;
				case 3:
					/* After '='. */
					if ((IS_ALPHA (*ptr)) || (IS_DIGIT (*ptr)) || (strchr (SAFE, *ptr))) {
						*value = *ptr;
						len = 1;

						state = 4;
					} else if (*ptr == '}') {
						if (!parent_list) {
							/* No parent list present. */
							fprintf (stderr, "[%s:%lu] No parent list present.\n", filename, nline);
							fclose (file);
							return -1;
						}

						/* The key has no value. */
						if (set_value (conf, key, "", 0) < 0) {
							/* Couldn't allocate memory. */
							fprintf (stderr, "[%s:%lu] Couldn't allocate memory.\n", filename, nline);
							fclose (file);
							return -1;
						}

						current_list = parent_list;
						parent_list = current_list->parent;
						key = NULL;

						state = 0;
					} else if (*ptr == '"') {
						len = 0;

						state = 6;
					} else if (*ptr == '\n') {
						/* The key has no value. */
						if (set_value (conf, key, "", 0) < 0) {
							/* Couldn't allocate memory. */
							fprintf (stderr, "[%s:%lu] Couldn't allocate memory.\n", filename, nline);
							fclose (file);
							return -1;
						}

						key = NULL;

						nline++;

						state = 0;
					} else if ((*ptr != '\r') && (*ptr != ' ') && (*ptr != '\t')) {
						/* Wrong character. */
						fprintf (stderr, "[%s:%lu] Wrong character found: [%c].\n", filename, nline, *ptr);
						fclose (file);
						return -1;
					}

					break;
				case 4:
					/* Reading value. */
					if ((IS_ALPHA (*ptr)) || (IS_DIGIT (*ptr)) || (strchr (SAFE, *ptr))) {
						if (len >= CONF_VALUE_MAXLEN) {
							/* Value too long. */
							fprintf (stderr, "[%s:%lu] Value too long (> %d).\n", filename, nline, CONF_VALUE_MAXLEN);
							fclose (file);
							return -1;
						}

						value[len++] = *ptr;
					} else if ((*ptr == '\r') || (*ptr == ' ') || (*ptr == '\t')) {
						if (set_value (conf, key, value, len) < 0) {
							/* Couldn't allocate memory. */
							fprintf (stderr, "[%s:%lu] Couldn't allocate memory.\n", filename, nline);
							fclose (file);
							return -1;
						}

						key = NULL;

						state = 5;
					} else if (*ptr == '}') {
						if (!parent_list) {
							/* No parent list present. */
							fprintf (stderr, "[%s:%lu] No parent list present.\n", filename, nline);
							fclose (file);
							return -1;
						}

						if (set_value (conf, key, value, len) < 0) {
							/* Couldn't allocate memory. */
							fprintf (stderr, "[%s:%lu] Couldn't allocate memory.\n", filename, nline);
							fclose (file);
							return -1;
						}

						current_list = parent_list;
						parent_list = current_list->parent;
						key = NULL;

						state = 0;
					} else if (*ptr == '\n') {
						if (set_value (conf, key, value, len) < 0) {
							/* Couldn't allocate memory. */
							fprintf (stderr, "[%s:%lu] Couldn't allocate memory.\n", filename, nline);
							fclose (file);
							return -1;
						}

						key = NULL;

						nline++;

						state = 0;
					} else {
						/* Wrong character. */
						fprintf (stderr, "[%s:%lu] Wrong character found: [%c].\n", filename, nline, *ptr);
						fclose (file);
						return -1;
					}

					break;
				case 5:
					/* After having read value. */
					if (*ptr == '\n') {
						nline++;

						state = 0;
					} else if (*ptr == '}') {
						if (!parent_list) {
							/* No parent list present. */
							fprintf (stderr, "[%s:%lu] No parent list present.\n", filename, nline);
							fclose (file);
							return -1;
						}

						current_list = parent_list;
						parent_list = current_list->parent;

						state = 0;
					} else if (*ptr == COMMENT) {
						state = 8;
					} else if ((*ptr != '\r') && (*ptr != ' ') && (*ptr != '\t')) {
						/* Wrong character. */
						fprintf (stderr, "[%s:%lu] Wrong character found: [%c].\n", filename, nline, *ptr);
						fclose (file);
						return -1;
					}

					break;
				case 6:
					/* The value is between quotation marks. */
					if (*ptr == '"') {
						if (set_value (conf, key, value, len) < 0) {
							/* Couldn't allocate memory. */
							fprintf (stderr, "[%s:%lu] Couldn't allocate memory.\n", filename, nline);
							fclose (file);
							return -1;
						}

						key = NULL;

						state = 5;
					} else if (*ptr == '\\') {
						state = 7;
					} else if (*ptr == '\n') {
						if (len >= CONF_VALUE_MAXLEN) {
							/* Value too long. */
							fprintf (stderr, "[%s:%lu] Value too long (> %d).\n", filename, nline, CONF_VALUE_MAXLEN);
							fclose (file);
							return -1;
						}

						value[len++] = *ptr;

						nline++;
					} else {
						if (len >= CONF_VALUE_MAXLEN) {
							/* Value too long. */
							fprintf (stderr, "[%s:%lu] Value too long (> %d).\n", filename, nline, CONF_VALUE_MAXLEN);
							fclose (file);
							return -1;
						}

						value[len++] = *ptr;
					}

					break;
				case 7:
					/* Escape character. */
					if (*ptr == 'r') {
						c = '\r';
					} else if (*ptr == 'n') {
						c = '\n';
					} else if (*ptr == 't') {
						c = '\t';
					} else {
						c = *ptr;
					}

					if (len >= CONF_VALUE_MAXLEN) {
						/* Value too long. */
						fprintf (stderr, "[%s:%lu] Value too long (> %d).\n", filename, nline, CONF_VALUE_MAXLEN);
						fclose (file);
						return -1;
					}

					value[len++] = c;

					state = 6;

					break;
				case 8:
					/* Comment. */
					if (*ptr == '\n') {
						nline++;

						state = 0;
					}

					break;
			}

			ptr++;
		}
	} while (bytes > 0);

	fclose (file);

	return (((state == 0) && (!parent_list))?0:-1);
}
Esempio n. 28
0
File: input.c Progetto: thewml/wml
token_type
next_token (token_data *td, read_type expansion, boolean in_string)
{
  int ch;
  token_type type = TOKEN_NONE;
  int quote_level;

  if (TOKEN_DATA_TYPE (&token_read) != TOKEN_VOID)
    {
      type = TOKEN_STRING;
      obstack_grow (&token_stack, TOKEN_DATA_TEXT (&token_read),
              strlen (TOKEN_DATA_TEXT (&token_read)));
      xfree ((voidstar) TOKEN_DATA_TEXT (&token_read));
      TOKEN_DATA_TYPE (&token_read) = TOKEN_VOID;
    }

  while (type == TOKEN_NONE)
    {
      obstack_free (&token_stack, token_bottom);
      obstack_1grow (&token_stack, '\0');
      token_bottom = obstack_finish (&token_stack);

      ch = peek_input ();
      if (ch == CHAR_EOF)                 /* EOF */
        {
#ifdef DEBUG_INPUT
          fprintf (stderr, "next_token -> EOF\n");
#endif
          return TOKEN_EOF;
        }

      if (ch == CHAR_MACRO)               /* MACRO TOKEN */
        {
          init_macro_token (td);
          (void) next_char ();
#ifdef DEBUG_INPUT
          print_token("next_token", TOKEN_MACDEF, td);
#endif
          return TOKEN_MACDEF;
        }

      (void) next_char ();
      if (IS_TAG(ch))             /* ESCAPED WORD */
        {
          if (lquote.length > 0 && MATCH (ch, lquote.string))
            {
              if (visible_quotes || expansion == READ_ATTR_VERB
                  || expansion == READ_ATTR_ASIS || expansion == READ_BODY)
                obstack_grow (&token_stack, lquote.string, lquote.length);
              while ((ch = next_char ()) != CHAR_EOF)
                {
                  if (rquote.length > 0 && MATCH (ch, rquote.string))
                    break;
                  obstack_1grow (&token_stack, ch);
                }
              if (visible_quotes || expansion == READ_ATTR_VERB
                  || expansion == READ_ATTR_ASIS || expansion == READ_BODY)
                {
                  obstack_grow (&token_stack, rquote.string, rquote.length);
                  type = TOKEN_STRING;
                }
              else
                type = TOKEN_QUOTED;
            }
          else
            {
              obstack_1grow (&token_stack, ch);
              if ((ch = peek_input ()) != CHAR_EOF)
                {
                  if (ch == '/')
                    {
                      obstack_1grow (&token_stack, '/');
                      (void) next_char ();
                      ch = peek_input ();
                    }
                  if (IS_ALPHA(ch))
                    {
                      ch = next_char ();
                      obstack_1grow (&token_stack, ch);
                      while ((ch = next_char ()) != CHAR_EOF && IS_ALNUM(ch))
                        {
                          obstack_1grow (&token_stack, ch);
                        }
                      if (ch == '*')
                        {
                          obstack_1grow (&token_stack, ch);
                          ch = peek_input ();
                        }
                      else
                        unget_input(ch);

                      if (IS_SPACE(ch) || IS_CLOSE(ch) || IS_SLASH (ch))
                        type = TOKEN_WORD;
                      else
                        type = TOKEN_STRING;
                    }
                  else
                    type = TOKEN_STRING;
                }
              else
                type = TOKEN_SIMPLE;        /* escape before eof */
            }
        }
      else if (IS_CLOSE(ch))
        {
          obstack_1grow (&token_stack, ch);
          type = TOKEN_SIMPLE;
        }
      else if (IS_ENTITY(ch))             /* entity  */
        {
          obstack_1grow (&token_stack, ch);
          if ((ch = peek_input ()) != CHAR_EOF)
            {
              if (IS_ALPHA(ch))
                {
                  ch = next_char ();
                  obstack_1grow (&token_stack, ch);
                  while ((ch = next_char ()) != CHAR_EOF && IS_ALNUM(ch))
                    {
                      obstack_1grow (&token_stack, ch);
                    }

                  if (ch == ';')
                    {
                      obstack_1grow (&token_stack, ch);
                      type = TOKEN_ENTITY;
                    }
                  else
                    {
                      type = TOKEN_STRING;
                      unget_input(ch);
                    }
                }
              else
                type = TOKEN_STRING;
            }
          else
            type = TOKEN_SIMPLE;        /* escape before eof */
        }
      else if (eolcomm.length > 0 && MATCH (ch, eolcomm.string))
        skip_line ();
      else if (expansion == READ_BODY)
        {
          if (ch == '"')
            obstack_1grow (&token_stack, CHAR_QUOTE);
          else
            obstack_1grow (&token_stack, ch);
          while ((ch = next_char ()) != CHAR_EOF
                  && ! IS_TAG(ch) && ! IS_CLOSE (ch))
            {
              if (eolcomm.length > 0 && MATCH (ch, eolcomm.string))
                {
                  skip_line ();
                  ch = CHAR_EOF;
                  break;
                }
              if (ch == '"')
                obstack_1grow (&token_stack, CHAR_QUOTE);
              else
                obstack_1grow (&token_stack, ch);
            }
          unget_input(ch);

          type = TOKEN_STRING;
        }
      /*  Below we know that expansion != READ_BODY  */
      else if (IS_ALPHA(ch))
        {
          obstack_1grow (&token_stack, ch);
          while ((ch = next_char ()) != CHAR_EOF && (IS_ALNUM(ch)))
            {
              obstack_1grow (&token_stack, ch);
            }
          if (ch == '*')
            {
              obstack_1grow (&token_stack, ch);
              ch = peek_input ();
            }
          else
            unget_input(ch);

          type = TOKEN_STRING;
        }
      else if (IS_RQUOTE(ch))
        {
          MP4HERROR ((EXIT_FAILURE, 0,
             "INTERNAL ERROR: CHAR_RQUOTE found."));
        }
      else if (IS_LQUOTE(ch))             /* QUOTED STRING */
        {
          quote_level = 1;
          while (1)
            {
              ch = next_char ();
              if (ch == CHAR_EOF)
                MP4HERROR ((EXIT_FAILURE, 0,
                   "INTERNAL ERROR: EOF in string"));

              if (IS_BGROUP(ch) || IS_EGROUP(ch))
                continue;
              else if (IS_RQUOTE(ch))
                {
                  quote_level--;
                  if (quote_level == 0)
                      break;
                }
              else if (IS_LQUOTE(ch))
                quote_level++;
              else
                obstack_1grow (&token_stack, ch);
            }
          type = TOKEN_QUOTED;
        }
      else if (IS_BGROUP(ch))             /* BEGIN GROUP */
        type = TOKEN_BGROUP;
      else if (IS_EGROUP(ch))             /* END GROUP */
        type = TOKEN_EGROUP;
      else if (ch == '"')                 /* QUOTED STRING */
        {
          switch (expansion)
          {
            case READ_NORMAL:
              obstack_1grow (&token_stack, CHAR_QUOTE);
              type = TOKEN_SIMPLE;
              break;

            case READ_ATTRIBUTE:
            case READ_ATTR_VERB:
              type = TOKEN_QUOTE;
              break;

            case READ_ATTR_ASIS:
            case READ_ATTR_QUOT:
              obstack_1grow (&token_stack, '"');
              type = TOKEN_QUOTE;
              break;

            default:
              MP4HERROR ((warning_status, 0,
                "INTERNAL ERROR: Unknown expansion type"));
              exit (1);
          }
        }
      else if (ch == '\\')
        {
          switch (expansion)
          {
            case READ_NORMAL:
              obstack_1grow (&token_stack, ch);
              type = TOKEN_SIMPLE;
              break;

            case READ_ATTRIBUTE:
            case READ_ATTR_QUOT:
              ch = next_char();
              if (ch == 'n')
                obstack_1grow (&token_stack, '\n');
              else if (ch == 't')
                obstack_1grow (&token_stack, '\t');
              else if (ch == 'r')
                obstack_1grow (&token_stack, '\r');
              else if (ch == '\\')
                obstack_1grow (&token_stack, ch);
              else if (ch == '"' && in_string)
                obstack_1grow (&token_stack, CHAR_QUOTE);
              else
                {
                  if (!(exp_flags & EXP_STD_BSLASH))
                    obstack_1grow (&token_stack, '\\');
                  obstack_1grow (&token_stack, ch);
                }

              type = TOKEN_STRING;
              break;

            case READ_ATTR_VERB:
              ch = next_char();
              if (ch == '"' && in_string)
                obstack_1grow (&token_stack, CHAR_QUOTE);
              else
                {
                  obstack_1grow (&token_stack, '\\');
                  obstack_1grow (&token_stack, ch);
                }

              type = TOKEN_STRING;
              break;

            case READ_ATTR_ASIS:
              obstack_1grow (&token_stack, ch);
              ch = next_char();
              obstack_1grow (&token_stack, ch);
              type = TOKEN_STRING;
              break;

            default:
              MP4HERROR ((warning_status, 0,
                "INTERNAL ERROR: Unknown expansion type"));
              exit (1);
          }
        }
      else /* EVERYTHING ELSE */
        {
          obstack_1grow (&token_stack, ch);

          if (IS_OTHER(ch) || IS_NUM(ch))
            type = TOKEN_STRING;
          else if (IS_SPACE(ch))
            {
              while ((ch = next_char ()) != CHAR_EOF && IS_SPACE(ch))
                obstack_1grow (&token_stack, ch);
              unget_input(ch);
              type = TOKEN_SPACE;
            }
          else
            type = TOKEN_SIMPLE;
        }
    }

  obstack_1grow (&token_stack, '\0');

  TOKEN_DATA_TYPE (td) = TOKEN_TEXT;
  TOKEN_DATA_TEXT (td) = obstack_finish (&token_stack);

#ifdef DEBUG_INPUT
  print_token("next_token", type, td);
#endif

  return type;
}
Esempio n. 29
0
static void find_and_change (char* in, int len) {
	// just to avoid underflows.. len can't be < then len(padding).
	if (!in || len < 1) {
		return;
	}
	char *end;
	RFindCTX ctx = {0};
	end = in + len;
//	type = TYPE_NONE;
	for (ctx.linebegin = in; in < end; ++in) {
		if (*in == '\n' || !*in) {
			if (ctx.type == TYPE_SYM && ctx.linecount < 1) {
				ctx.linecount++;
				ctx.linebegin = in + 1;
				continue;
			}
			if (ctx.type != TYPE_NONE && ctx.right && ctx.left && ctx.rightlen > 0 && ctx.leftlen > 0) {
				char* copy = NULL;
				if (ctx.leftlen > ctx.rightlen) {
					copy = (char*) malloc (ctx.leftlen);
					if (copy) {
						memcpy (copy, ctx.left, ctx.leftlen);
						memcpy (ctx.left, ctx.right, ctx.rightlen);
						memmove (ctx.comment - ctx.leftlen + ctx.rightlen, ctx.comment, ctx.right - ctx.comment);
						memcpy (ctx.right - ctx.leftlen + ctx.rightlen, copy, ctx.leftlen);
					}
				} else if (ctx.leftlen < ctx.rightlen) {
					if (ctx.linecount < 1) {
						copy = (char*) malloc (ctx.rightlen);
						if (copy) {
							memcpy (copy, ctx.right, ctx.rightlen);
							memcpy (ctx.right + ctx.rightlen - ctx.leftlen, ctx.left, ctx.leftlen);
							memmove (ctx.comment + ctx.rightlen - ctx.leftlen, ctx.comment, ctx.right - ctx.comment);
							memcpy (ctx.left + ctx.rightlen - ctx.leftlen, copy, ctx.rightlen);
						}
					} else {
//						copy = (char*) malloc (ctx.linebegin - ctx.left);
//						if (copy) {
//							memcpy (copy, ctx.left, ctx.linebegin - ctx.left);
						memset (ctx.right - ctx.leftpos, ' ', ctx.leftpos);
						*(ctx.right - ctx.leftpos - 1) = '\n';
//							memcpy (ctx.comment + 3, copy, ctx.linebegin - ctx.left);
						memset (ctx.left, ' ', ctx.leftlen);
						memset (ctx.linebegin - ctx.leftlen, ' ', ctx.leftlen);
//						}
					}
				} else if (ctx.leftlen == ctx.rightlen) {
					copy = (char*) malloc (ctx.leftlen);
					if (copy) {
						memcpy (copy, ctx.right, ctx.leftlen);
						memcpy (ctx.right, ctx.left, ctx.leftlen);
						memcpy (ctx.left, copy, ctx.leftlen);
					}
				}
				free (copy);
			}
			memset (&ctx, 0, sizeof (ctx));
			ctx.linebegin = in + 1;
		} else if (!ctx.comment && *in == ';' && in[1] == ' ') {
			ctx.comment = in - 1;
			ctx.comment[1] = '/';
			ctx.comment[2] = '/';
			while (!IS_WHITESPACE (*(ctx.comment - ctx.commentcolor))) {
				ctx.commentcolor++;
			}
			ctx.commentcolor--;
		} else if (!ctx.comment && ctx.type == TYPE_NONE) {
			if (IS_STRING (in, ctx)) {
				ctx.type = TYPE_STR;
				ctx.left = in;
				while (!IS_WHITESPACE (*(ctx.left - ctx.leftcolor))) {
					ctx.leftcolor++;
				}
				ctx.leftcolor--;
				ctx.leftpos = ctx.left - ctx.linebegin;
			} else if (IS_SYMBOL (in, ctx)) {
				ctx.type = TYPE_SYM;
				ctx.left = in;
				while (!IS_WHITESPACE (*(ctx.left - ctx.leftcolor))) {
					ctx.leftcolor++;
				}
				ctx.leftcolor--;
				ctx.leftpos = ctx.left - ctx.linebegin;
			}
		} else if (ctx.type == TYPE_STR) {
			if (!ctx.leftlen && ctx.left && IS_WHITESPACE (*in)) {
				ctx.leftlen = in - ctx.left;
			} else if (ctx.comment && *in == '"' && in[-1] != '\\') {
				if (!ctx.right) {
					ctx.right = in;
					while (!IS_WHITESPACE (*(ctx.right - ctx.rightcolor))) {
						ctx.rightcolor++;
					}
					ctx.rightcolor--;
				} else {
					ctx.rightlen = in - ctx.right + 1;
				}
			}
		} else if (ctx.type == TYPE_SYM) {
			if (!ctx.leftlen && ctx.left && IS_WHITESPACE (*in)) {
				ctx.leftlen = in - ctx.left + 3;
			} else if (ctx.comment && *in == '(' && IS_ALPHA (in[-1]) && !ctx.right) {
				// ok so i've found a function written in this way:
				// type = [const|void|int|float|double|short|long]
				// type fcn_name (type arg1, type arg2, ...)
				// right now 'in' points at '(', but the function name is before, so i'll go back
				// till a space is found
				// 'int print(const char*, ...)'
				//           ^
				ctx.right = in - 1;
				while (IS_ALPHA (*ctx.right) || *ctx.right == '_' || *ctx.right == '*') {
					ctx.right--;
				}
				// 'int print(const char*, ...)'
				//     ^
				// right now 'in' points at ' ' before 'p' , but there can be a return value
				// like 'int' in 'int print(const char*, ...)'.
				// so to find for example 'int' we have to go back till a space is found.
				// if a non alpha is found, then we can cut from the function name
				if (*ctx.right == ' ') {
					ctx.right--;
					while (IS_ALPHA (*ctx.right) || *ctx.right == '_' || *ctx.right == '*') {
						ctx.right--;
					}
					// moving forward since it points now to non alpha.
					ctx.right++;
				}
				while (!IS_WHITESPACE (*(ctx.right - ctx.rightcolor))) {
					ctx.rightcolor++;
				}
				ctx.rightcolor--;
			} else if (ctx.comment && *in == ')' && in[1] != '\'') {
				ctx.rightlen = in - ctx.right + 1;
			}
		}
	}
}
Esempio n. 30
0
bool resolver::fill_question(const char* name, size_t namelen, rr_type type, unsigned char* buf, size_t& size)
{
	const char* ptr = name;
	const char* end = name + namelen;

	size_t l = 1; // Zero length octect for the null label of the root.
	size_t labellen = 0;

	int state = 0;

	while (ptr < end) {
		unsigned char c = (unsigned char) *ptr++;

		switch (state) {
			case 0:
				if ((l += 2) > NAME_MAX_LEN) {
					return false;
				}

				if (!IS_ALPHA(c)) {
					return false;
				}

				buf++; // Skip length octect.
				*buf++ = c;

				labellen = 1;

				state = 1;

				break;
			case 1:
				if (c == '.') {
					buf[-(1 + labellen)] = (unsigned char) labellen;

					state = 0;
				} else if ((IS_ALPHA(c)) || (IS_DIGIT(c))) {
					if (++l > NAME_MAX_LEN) {
						return false;
					}

					if (++labellen > LABEL_MAX_LEN) {
						return false;
					}

					*buf++ = c;
				} else if (c == '-') {
					if (++l > NAME_MAX_LEN) {
						return false;
					}

					if (++labellen > LABEL_MAX_LEN) {
						return false;
					}

					*buf++ = c;

					state = 2;
				} else {
					return false;
				}

				break;
			case 2:
				if ((IS_ALPHA(c)) || (IS_DIGIT(c))) {
					if (++l > NAME_MAX_LEN) {
						return false;
					}

					if (++labellen > LABEL_MAX_LEN) {
						return false;
					}

					*buf++ = c;

					state = 1;
				} else {
					return false;
				}

				break;
		}
	}

	if (state != 1) {
		return false;
	}

	buf[-(1 + labellen)] = (unsigned char) labellen;

	*buf++ = 0; // Zero length octect for the null label of the root.

	// QTYPE.
	*buf++ = (unsigned char) ((type >> 8) & 0xff);
	*buf++ = (unsigned char) (type & 0xff);

	// CLASS.
	*buf++ = 0;
	*buf = 1; // IN (Internet).

	size = l + 4;

	return true;
}