示例#1
0
文件: minIni.c 项目: jdaheron/BLDR
int ini_getkey_OpenedFile(
		const mTCHAR *Section,
		int idx,
		mTCHAR *Buffer,
		int BufferSize,
		INI_FILETYPE* pFile
)
{
	int ok = 0;
	int pos = 0;

	if (Buffer == NULL || BufferSize <= 0 || idx < 0)
		return 0;

	ini_tell(pFile, &pos);

	ok = getkeystring(pFile, Section, NULL, -1, idx, Buffer, BufferSize);

	if (!ok)
		*Buffer = '\0';

	(void) ini_seek(pFile, &pos);

	return _tcslen(Buffer);
}
示例#2
0
文件: zle_misc.c 项目: Jaharmi/zsh
mod_export void
makesuffixstr(char *f, char *s, int n)
{
    if (f) {
	zsfree(suffixfunc);
	suffixfunc = ztrdup(f);
	suffixfunclen = n;
    } else if (s) {
	int inv, i, z = 0;
	ZLE_STRING_T ws, lasts, wptr;

	if (*s == '^' || *s == '!') {
	    inv = 1;
	    s++;
	} else
	    inv = 0;
	s = getkeystring(s, &i, GETKEYS_SUFFIX, &z);
	s = metafy(s, i, META_USEHEAP);
	ws = stringaszleline(s, 0, &i, NULL, NULL);

	if (z)
	    suffixnoinslen = inv ? 0 : n;
	else if (inv) {
	    /*
	     * negative match, \- wasn't present, so it *should*
	     * have this suffix length
	     */
	    suffixnoinslen = n;
	}

	lasts = wptr = ws;
	while (i) {
	    if (i >= 3 && wptr[1] == ZWC('-')) {
		ZLE_CHAR_T str[2];

		if (wptr > lasts)
		    addsuffix(inv ? SUFTYP_NEGSTR : SUFTYP_POSSTR, 0,
			      lasts, wptr - lasts, n);
		str[0] = *wptr;
		str[1] = wptr[2];
		addsuffix(inv ? SUFTYP_NEGRNG : SUFTYP_POSRNG, 0,
			  str, 2, n);

		wptr += 3;
		i -= 3;
		lasts = wptr;
	    } else {
		wptr++;
		i--;
	    }
	}
	if (wptr > lasts)
	    addsuffix(inv ? SUFTYP_NEGSTR : SUFTYP_POSSTR, 0,
		      lasts, wptr - lasts, n);
	free(ws);
    } else
	makesuffix(n);
}
示例#3
0
文件: prompt.c 项目: jackleaks/zsh
static void
set_colour_code(char *str, char **var)
{
    char *keyseq;
    int len;

    zsfree(*var);
    keyseq = getkeystring(str, &len, GETKEYS_BINDKEY, NULL);
    *var = metafy(keyseq, len, META_DUP);
}
示例#4
0
文件: zle_misc.c 项目: MPOWER4RU/zsh
mod_export void
makesuffixstr(char *f, char *s, int n)
{
    if (f) {
	zsfree(suffixfunc);
	suffixfunc = ztrdup(f);
	suffixfunclen = n;
    } else if (s) {
	int inv, i, z = 0;
	ZLE_STRING_T ws, lasts, wptr;

	if (*s == '^' || *s == '!') {
	    inv = 1;
	    s++;
	} else
	    inv = 0;
	s = getkeystring(s, &i, GETKEYS_SUFFIX, &z);
	s = metafy(s, i, META_USEHEAP);
	ws = stringaszleline(s, 0, &i, NULL, NULL);

	/* Remove suffix on uninsertable characters if  \- was given *
	 * and the character class wasn't negated -- or vice versa.  */
	suffixnoinsrem = z ^ inv;
	suffixlen = n;

	lasts = wptr = ws;
	while (i) {
	    if (i >= 3 && wptr[1] == ZWC('-')) {
		ZLE_CHAR_T str[2];

		if (wptr > lasts)
		    addsuffix(inv ? SUFTYP_NEGSTR : SUFTYP_POSSTR, 0,
			      lasts, wptr - lasts, n);
		str[0] = *wptr;
		str[1] = wptr[2];
		addsuffix(inv ? SUFTYP_NEGRNG : SUFTYP_POSRNG, 0,
			  str, 2, n);

		wptr += 3;
		i -= 3;
		lasts = wptr;
	    } else {
		wptr++;
		i--;
	    }
	}
	if (wptr > lasts)
	    addsuffix(inv ? SUFTYP_NEGSTR : SUFTYP_POSSTR, 0,
		      lasts, wptr - lasts, n);
	free(ws);
    } else
	makesuffix(n);
}
示例#5
0
/** ini_getkey()
 * \param Section     the name of the section to browse through, or NULL to
 *                    browse through the keys outside any section
 * \param idx         the zero-based sequence number of the key to return
 * \param Buffer      a pointer to the buffer to copy into
 * \param BufferSize  the maximum number of characters to copy
 * \param Filename    the name and full path of the .ini file to read from
 *
 * \return            the number of characters copied into the supplied buffer
 */
int  ini_getkey(const TCHAR *Section, int idx, TCHAR *Buffer, int BufferSize, const TCHAR *Filename)
{
  INI_FILETYPE fp;
  int ok = 0;

  if (Buffer == NULL || BufferSize <= 0 || idx < 0)
    return 0;
  if (ini_openread(Filename, &fp)) {
    ok = getkeystring(&fp, Section, NULL, -1, idx, Buffer, BufferSize);
    (void)ini_close(&fp);
  } /* if */
  if (!ok)
    *Buffer = '\0';
  return _tcslen(Buffer);
}
示例#6
0
/** ini_gets()
 * \param Section     the name of the section to search for
 * \param Key         the name of the entry to find the value of
 * \param DefValue    default string in the event of a failed read
 * \param Buffer      a pointer to the buffer to copy into
 * \param BufferSize  the maximum number of characters to copy
 * \param Filename    the name and full path of the .ini file to read from
 *
 * \return            the number of characters copied into the supplied buffer
 */
int ini_gets(const TCHAR *Section, const TCHAR *Key, const TCHAR *DefValue,
             TCHAR *Buffer, int BufferSize, const TCHAR *Filename)
{
  INI_FILETYPE fp;
  int ok = 0;

  if (Buffer == NULL || BufferSize <= 0 || Key == NULL)
    return 0;
  if (ini_openread(Filename, &fp)) {
    ok = getkeystring(&fp, Section, Key, -1, -1, Buffer, BufferSize);
    (void)ini_close(&fp);
  } /* if */
  if (!ok)
    save_strncpy(Buffer, DefValue, BufferSize, QUOTE_NONE);
  return _tcslen(Buffer);
}
示例#7
0
/** Profile_GetString()
* \param Section     the name of the section to search for
* \param Key         the name of the entry to find the value of
* \param DefValue    default string in the event of a failed read
* \param Buffer      a pointer to the buffer to copy into
* \param BufferSize  the maximum number of characters to copy
*
* \return            the number of characters copied into the supplied buffer
*/
int Profile_GetString(const char *Section, const char *Key, const char *DefValue,
char *Buffer, int BufferSize)
{
    int ok = 0;

    if (Buffer == NULL || BufferSize <= 0 || Key == NULL)
    return 0;
    if (g_BufferAddr != NULL)
    {
    ok = getkeystring(Section, Key, -1, -1, Buffer, BufferSize);
    Profile_seek(0);
    } /* if */
    if (!ok)
    save_strncpy(Buffer, DefValue, BufferSize, QUOTE_NONE);
    return _tcslen(Buffer);
}
示例#8
0
文件: minIni.c 项目: jdaheron/BLDR
int ini_gets_OpenedFile(
	const TCHAR *Section,
	const TCHAR *Key,
	const TCHAR *DefValue,
	TCHAR *Buffer,
	int BufferSize,
	INI_FILETYPE* pFile
)
{
	int ok = 0;
	int pos = 0;

	if (Buffer == NULL || BufferSize <= 0 || Key == NULL)
		return 0;

//	(void) ini_seek(pFile, &pos);

	ok = getkeystring(pFile, Section, Key, -1, -1, Buffer, BufferSize);

	if (!ok)
		save_strncpy(Buffer, DefValue, BufferSize, QUOTE_NONE);

	return _tcslen(Buffer);
}
示例#9
0
文件: minIni.c 项目: dfink08/thesis
/** ini_gets()
 * \param Section     the name of the section to search for
 * \param Key         the name of the entry to find the value of
 * \param DefValue    default string in the event of a failed read
 * \param Buffer      a pointer to the buffer to copy into
 * \param BufferSize  the maximum number of characters to copy
 * \param Filename    the name and full path of the .ini file to read from
 *
 * \return            the number of characters copied into the supplied buffer
 */
int ini_gets(const TCHAR *Section, const TCHAR *Key, const TCHAR *DefValue,
             TCHAR *Buffer, int BufferSize, const TCHAR *Filename)
{
  INI_FILETYPE fp;

//FILE* fp = fopen("./config.txt","rb");


  int ok = 0;

/*int i;
printf("file pointer, %p\n", fp);

  u_char* data;
  data = (u_char*) &fp;

  printf("fopen:::");

	    for (i=0; i<=(20); i++)	//-1 to account for not starting at 1
	    {
		printf("%s:", data[i]);
	    }
		printf("\n"); 
*/


  if (Buffer == NULL || BufferSize <= 0 || Key == NULL)
    return 0;
  if (ini_openread(Filename, &fp)) {
    ok = getkeystring(&fp, Section, Key, -1, -1, Buffer, BufferSize);
    (void)ini_close(&fp);
  } /* if */
  if (!ok)
    save_strncpy(Buffer, DefValue, BufferSize, QUOTE_NONE);
  return _tcslen(Buffer);
}
示例#10
0
/** ini_puts()
 * \param Section     the name of the section to write the string in
 * \param Key         the name of the entry to write, or NULL to erase all keys in the section
 * \param Value       a pointer to the buffer the string, or NULL to erase the key
 * \param Filename    the name and full path of the .ini file to write to
 *
 * \return            1 if successful, otherwise 0
 */
int ini_puts(const TCHAR *Section, const TCHAR *Key, const TCHAR *Value, const TCHAR *Filename)
{
  INI_FILETYPE rfp;
  INI_FILETYPE wfp;
  INI_FILEPOS mark;
  TCHAR *sp, *ep;
  TCHAR LocalBuffer[INI_BUFFERSIZE];
  int len, match, flag, cachelen;

  assert(Filename != NULL);
  if (!ini_openread(Filename, &rfp)) {
    /* If the .ini file doesn't exist, make a new file */
    if (Key != NULL && Value != NULL) {
      if (!ini_openwrite(Filename, &wfp))
        return 0;
      writesection(LocalBuffer, Section, &wfp);
      writekey(LocalBuffer, Key, Value, &wfp);
      (void)ini_close(&wfp);
    } /* if */
    return 1;
  } /* if */

  /* If parameters Key and Value are valid (so this is not an "erase" request)
   * and the setting already exists and it already has the correct value, do
   * nothing. This early bail-out avoids rewriting the INI file for no reason.
   */
  if (Key != NULL && Value != NULL) {
    (void)ini_tell(&rfp, &mark);
    match = getkeystring(&rfp, Section, Key, -1, -1, LocalBuffer, sizearray(LocalBuffer));
    if (match && _tcscmp(LocalBuffer,Value) == 0) {
      (void)ini_close(&rfp);
      return 1;
    } /* if */
    /* key not found, or different value -> proceed (but rewind the input file first) */
    (void)ini_seek(&rfp, &mark);
  } /* if */

  /* Get a temporary file name to copy to. Use the existing name, but with
   * the last character set to a '~'.
   */
  ini_tempname(LocalBuffer, Filename, INI_BUFFERSIZE);
  if (!ini_openwrite(LocalBuffer, &wfp)) {
    (void)ini_close(&rfp);
    return 0;
  } /* if */
  (void)ini_tell(&rfp, &mark);
  cachelen = 0;

  /* Move through the file one line at a time until a section is
   * matched or until EOF. Copy to temp file as it is read.
   */
  len = (Section != NULL) ? _tcslen(Section) : 0;
  if (len > 0) {
    do {
      if (!ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp)) {
        /* Failed to find section, so add one to the end */
        flag = cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark);
        if (Key!=NULL && Value!=NULL) {
          if (!flag)
            (void)ini_write(INI_LINETERM, &wfp);  /* force a new line behind the last line of the INI file */
          writesection(LocalBuffer, Section, &wfp);
          writekey(LocalBuffer, Key, Value, &wfp);
        } /* if */
        return close_rename(&rfp, &wfp, Filename, LocalBuffer);  /* clean up and rename */
      } /* if */
      /* Copy the line from source to dest, but not if this is the section that
       * we are looking for and this section must be removed
       */
      sp = skipleading(LocalBuffer);
      ep = _tcschr(sp, ']');
      match = (*sp == '[' && ep != NULL && (int)(ep-sp-1) == len && _tcsnicmp(sp + 1,Section,len) == 0);
      if (!match || Key != NULL) {
        if (!cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE)) {
          cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark);
          (void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp);
          cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE);
        } /* if */
      } /* if */
    } while (!match);
  } /* if */
  cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark);
  /* when deleting a section, the section head that was just found has not been
   * copied to the output file, but because this line was not "accumulated" in
   * the cache, the position in the input file was reset to the point just
   * before the section; this must now be skipped (again)
   */
  if (Key == NULL) {
    (void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp);
    (void)ini_tell(&rfp, &mark);
  } /* if */

  /* Now that the section has been found, find the entry. Stop searching
   * upon leaving the section's area. Copy the file as it is read
   * and create an entry if one is not found.
   */
  len = (Key!=NULL) ? _tcslen(Key) : 0;
  for( ;; ) {
    if (!ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp)) {
      /* EOF without an entry so make one */
      flag = cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark);
      if (Key!=NULL && Value!=NULL) {
        if (!flag)
          (void)ini_write(INI_LINETERM, &wfp);  /* force a new line behind the last line of the INI file */
        writekey(LocalBuffer, Key, Value, &wfp);
      } /* if */
      return close_rename(&rfp, &wfp, Filename, LocalBuffer);  /* clean up and rename */
    } /* if */
    sp = skipleading(LocalBuffer);
    ep = _tcschr(sp, '='); /* Parse out the equal sign */
    if (ep == NULL)
      ep = _tcschr(sp, ':');
    match = (ep != NULL && (int)(skiptrailing(ep,sp)-sp) == len && _tcsnicmp(sp,Key,len) == 0);
    if ((Key != NULL && match) || *sp == '[')
      break;  /* found the key, or found a new section */
    /* copy other keys in the section */
    if (Key == NULL) {
      (void)ini_tell(&rfp, &mark);  /* we are deleting the entire section, so update the read position */
    } else {
      if (!cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE)) {
        cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark);
        (void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp);
        cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE);
      } /* if */
    } /* if */
  } /* for */
  /* the key was found, or we just dropped on the next section (meaning that it
   * wasn't found); in both cases we need to write the key, but in the latter
   * case, we also need to write the line starting the new section after writing
   * the key
   */
  flag = (*sp == '[');
  cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark);
  if (Key != NULL && Value != NULL)
    writekey(LocalBuffer, Key, Value, &wfp);
  /* cache_flush() reset the "read pointer" to the start of the line with the
   * previous key or the new section; read it again (because writekey() destroyed
   * the buffer)
   */
  (void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp);
  if (flag) {
    /* the new section heading needs to be copied to the output file */
    cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE);
  } else {
    /* forget the old key line */
    (void)ini_tell(&rfp, &mark);
  } /* if */
  /* Copy the rest of the INI file */
  while (ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp)) {
    if (!cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE)) {
      cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark);
      (void)ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp);
      cache_accum(LocalBuffer, &cachelen, INI_BUFFERSIZE);
    } /* if */
  } /* while */
  cache_flush(LocalBuffer, &cachelen, &rfp, &wfp, &mark);
  return close_rename(&rfp, &wfp, Filename, LocalBuffer);  /* clean up and rename */
}
示例#11
0
/** ini_puts()
 * \param Section     the name of the section to write the string in
 * \param Key         the name of the entry to write, or NULL to erase all keys in the section
 * \param Value       a pointer to the buffer the string, or NULL to erase the key
 * \param Filename    the name and full path of the .ini file to write to
 *
 * \return            1 if successful, otherwise 0
 */
int ini_puts(const TCHAR *Section, const TCHAR *Key, const TCHAR *Value, const TCHAR *Filename)
{
  INI_FILETYPE rfp;
  INI_FILETYPE wfp;
  TCHAR *sp, *ep;
  TCHAR LocalBuffer[INI_BUFFERSIZE];
  int len, match, count;

  assert(Filename!=NULL);
  if (!ini_openread(Filename, &rfp)) {
    /* If the .ini file doesn't exist, make a new file */
    if (Key!=NULL && Value!=NULL) {
      if (!ini_openwrite(Filename, &wfp))
        return 0;
      writesection(LocalBuffer, Section, &wfp);
      writekey(LocalBuffer, Key, Value, &wfp);
      ini_close(&wfp);
    } /* if */
    return 1;
  } /* if */

  /* If parameters Key and Value are valid (so this is not an "erase" request)
   * and the setting already exists and it already has the correct value, do
   * nothing. This early bail-out avoids rewriting the INI file for no reason.
   */
  if (Key!=NULL && Value!=NULL) {
    match = getkeystring(&rfp, Section, Key, -1, -1, LocalBuffer, sizearray(LocalBuffer));
    if (match && _tcscmp(LocalBuffer,Value)==0) {
      ini_close(&rfp);
      return 1;
    } /* if */
    /* key not found, or different value -> proceed (but rewind the input file first) */
    ini_rewind(&rfp);
  } /* if */

  /* Get a temporary file name to copy to. Use the existing name, but with
   * the last character set to a '~'.
   */
  ini_tempname(LocalBuffer, Filename, INI_BUFFERSIZE);
  if (!ini_openwrite(LocalBuffer, &wfp)) {
    ini_close(&rfp);
    return 0;
  } /* if */

  /* Move through the file one line at a time until a section is
   * matched or until EOF. Copy to temp file as it is read.
   */
  count = 0;
  len = (Section != NULL) ? _tcslen(Section) : 0;
  if (len > 0) {
    do {
      if (!ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp)) {
        /* Failed to find section, so add one to the end */
        if (Key!=NULL && Value!=NULL) {
            ini_write(INI_LINETERM, &wfp);  /* force a new line (there may not have been one) behind the last line of the INI file */
            writesection(LocalBuffer, Section, &wfp);
            writekey(LocalBuffer, Key, Value, &wfp);
        } /* if */
        /* Clean up and rename */
        ini_close(&rfp);
        ini_close(&wfp);
        ini_remove(Filename);
        ini_tempname(LocalBuffer, Filename, INI_BUFFERSIZE);
        ini_rename(LocalBuffer, Filename);
        return 1;
      } /* if */
      /* Copy the line from source to dest, but not if this is the section that
       * we are looking for and this section must be removed
       */
      sp = skipleading(LocalBuffer);
      ep = _tcschr(sp, ']');
      match = (*sp == '[' && ep != NULL && (int)(ep-sp-1) == len && _tcsnicmp(sp + 1,Section,len) == 0);
      if (!match || Key!=NULL) {
        /* Remove blank lines, but insert a blank line (possibly one that was
         * removed on the previous iteration) before a new section. This creates
         * "neat" INI files.
         */
        if (_tcslen(sp) > 0) {
          if (*sp == '[' && count > 0)
            ini_write(INI_LINETERM, &wfp);
          ini_write(sp, &wfp);
          count++;
        } /* if */
      } /* if */
    } while (!match);
  } /* if */

  /* Now that the section has been found, find the entry. Stop searching
   * upon leaving the section's area. Copy the file as it is read
   * and create an entry if one is not found.
   */
  len = (Key!=NULL) ? _tcslen(Key) : 0;
  for( ;; ) {
    if (!ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp)) {
      /* EOF without an entry so make one */
      if (Key!=NULL && Value!=NULL) {
          ini_write(INI_LINETERM, &wfp);  /* force a new line (there may not have been one) behind the last line of the INI file */
          writekey(LocalBuffer, Key, Value, &wfp);
      } /* if */
      /* Clean up and rename */
      ini_close(&rfp);
      ini_close(&wfp);
      ini_remove(Filename);
      ini_tempname(LocalBuffer, Filename, INI_BUFFERSIZE);
      ini_rename(LocalBuffer, Filename);
      return 1;
    } /* if */
    sp = skipleading(LocalBuffer);
    ep = _tcschr(sp, '='); /* Parse out the equal sign */
    if (ep == NULL)
      ep = _tcschr(sp, ':');
    match = (ep != NULL && (int)(ep-sp) == len && _tcsnicmp(sp,Key,len) == 0);
    if ((Key!=NULL && match) || *sp == '[')
      break;  /* found the key, or found a new section */
    /* in the section that we re-write, do not copy empty lines */
    if (Key!=NULL && _tcslen(sp) > 0)
      ini_write(sp, &wfp);
  } /* for */
  if (*sp == '[') {
    /* found start of new section, the key was not in the specified
     * section, so we add it just before the new section
     */
    if (Key!=NULL && Value!=NULL) {
      /* We cannot use "writekey()" here, because we need to preserve the
       * contents of LocalBuffer.
       */
      ini_write(Key, &wfp);
      ini_write("=", &wfp);
      ini_write(Value, &wfp);
      ini_write(INI_LINETERM INI_LINETERM, &wfp); /* put a blank line between the current and the next section */
    } /* if */
    /* write the new section header that we read previously */
    ini_write(sp, &wfp);
  } else {
    /* We found the key; ignore the line just read (with the key and
     * the current value) and write the key with the new value.
     */
    if (Key!=NULL && Value!=NULL)
      writekey(LocalBuffer, Key, Value, &wfp);
  } /* if */
  /* Copy the rest of the INI file (removing empty lines, except before a section) */
  while (ini_read(LocalBuffer, INI_BUFFERSIZE, &rfp)) {
    sp = skipleading(LocalBuffer);
    if (_tcslen(sp) > 0) {
      if (*sp == '[')
        ini_write(INI_LINETERM, &wfp);
      ini_write(sp, &wfp);
    } /* if */
  } /* while */
  /* Clean up and rename */
  ini_close(&rfp);
  ini_close(&wfp);
  ini_remove(Filename);
  ini_tempname(LocalBuffer, Filename, INI_BUFFERSIZE);
  ini_rename(LocalBuffer, Filename);
  return 1;
}
示例#12
0
文件: math.c 项目: blueyed/zsh
static int
zzlex(void)
{
    int cct = 0;
    char *ie;
    yyval.type = MN_INTEGER;

    for (;; cct = 0)
	switch (*ptr++) {
	case '+':
	    if (*ptr == '+') {
		ptr++;
		return (unary) ? PREPLUS : POSTPLUS;
	    }
	    if (*ptr == '=') {
		ptr++;
		return PLUSEQ;
	    }
	    return (unary) ? UPLUS : PLUS;
	case '-':
	    if (*ptr == '-') {
		ptr++;
		return (unary) ? PREMINUS : POSTMINUS;
	    }
	    if (*ptr == '=') {
		ptr++;
		return MINUSEQ;
	    }
	    if (unary) {
		if (idigit(*ptr) || *ptr == '.') {
		    ptr--;
		    return lexconstant();
		} else
		    return UMINUS;
	    } else
		return MINUS;
	case '(':
	    return M_INPAR;
	case ')':
	    return M_OUTPAR;
	case '!':
	    if (*ptr == '=') {
		ptr++;
		return NEQ;
	    }
	    return NOT;
	case '~':
	    return COMP;
	case '&':
	    if (*ptr == '&') {
		if (*++ptr == '=') {
		    ptr++;
		    return DANDEQ;
		}
		return DAND;
	    } else if (*ptr == '=') {
		ptr++;
		return ANDEQ;
	    }
	    return AND;
	case '|':
	    if (*ptr == '|') {
		if (*++ptr == '=') {
		    ptr++;
		    return DOREQ;
		}
		return DOR;
	    } else if (*ptr == '=') {
		ptr++;
		return OREQ;
	    }
	    return OR;
	case '^':
	    if (*ptr == '^') {
		if (*++ptr == '=') {
		    ptr++;
		    return DXOREQ;
		}
		return DXOR;
	    } else if (*ptr == '=') {
		ptr++;
		return XOREQ;
	    }
	    return XOR;
	case '*':
	    if (*ptr == '*') {
		if (*++ptr == '=') {
		    ptr++;
		    return POWEREQ;
		}
		return POWER;
	    }
	    if (*ptr == '=') {
		ptr++;
		return MULEQ;
	    }
	    return MUL;
	case '/':
	    if (*ptr == '=') {
		ptr++;
		return DIVEQ;
	    }
	    return DIV;
	case '%':
	    if (*ptr == '=') {
		ptr++;
		return MODEQ;
	    }
	    return MOD;
	case '<':
	    if (*ptr == '<') {
		if (*++ptr == '=') {
		    ptr++;
		    return SHLEFTEQ;
		}
		return SHLEFT;
	    } else if (*ptr == '=') {
		ptr++;
		return LEQ;
	    }
	    return LES;
	case '>':
	    if (*ptr == '>') {
		if (*++ptr == '=') {
		    ptr++;
		    return SHRIGHTEQ;
		}
		return SHRIGHT;
	    } else if (*ptr == '=') {
		ptr++;
		return GEQ;
	    }
	    return GRE;
	case '=':
	    if (*ptr == '=') {
		ptr++;
		return DEQ;
	    }
	    return EQ;
	case '$':
	    yyval.u.l = mypid;
	    return NUM;
	case '?':
	    if (unary) {
		yyval.u.l = lastval;
		return NUM;
	    }
	    return QUEST;
	case ':':
	    return COLON;
	case ',':
	    return COMMA;
	case '\0':
	    ptr--;
	    return EOI;
	case '[':
	    {
		int n, checkradix = 0;

		if (idigit(*ptr)) {
		    n = zstrtol(ptr, &ptr, 10);
		    if (*ptr != ']' || !idigit(*++ptr)) {
			zerr("bad base syntax");
			return EOI;
		    }
		    yyval.u.l = zstrtol(ptr, &ptr, lastbase = n);
		    return NUM;
		}
		if (*ptr == '#') {
		    n = 1;
		    if (*++ptr == '#') {
			n = -1;
			ptr++;
		    }
		    if (!idigit(*ptr) && *ptr != '_')
			goto bofs;
		    if (idigit(*ptr)) {
			outputradix = n * zstrtol(ptr, &ptr, 10);
			checkradix = 1;
		    }
		    if (*ptr == '_') {
			ptr++;
			if (idigit(*ptr))
			    outputunderscore = zstrtol(ptr, &ptr, 10);
			else
			    outputunderscore = 3;
		    }
		} else {
		    bofs:
		    zerr("bad output format specification");
		    return EOI;
		}
		if(*ptr != ']')
			goto bofs;
		if (checkradix) {
		    n = (outputradix < 0) ? -outputradix : outputradix;
		    if (n < 2 || n > 36) {
			zerr("invalid base (must be 2 to 36 inclusive): %d",
			     outputradix);
			return EOI;
		    }
		}
		ptr++;
		break;
	    }
	case ' ':
	case '\t':
	case '\n':
	    break;
	/* Fall through! */
	default:
	    if (idigit(*--ptr) || *ptr == '.')
		return lexconstant();
	    if (*ptr == '#') {
		if (*++ptr == '\\' || *ptr == '#') {
		    int v;

		    ptr++;
		    if (!*ptr) {
			zerr("character missing after ##");
			return EOI;
		    }
		    ptr = getkeystring(ptr, NULL, GETKEYS_MATH, &v);
		    yyval.u.l = v;
		    return NUM;
		}
		cct = 1;
	    }
	    if ((ie = itype_end(ptr, IIDENT, 0)) != ptr) {
		int func = 0;
		char *p;

		p = ptr;
		ptr = ie;
		if (*ptr == '[' || (!cct && *ptr == '(')) {
		    char op = *ptr, cp = ((*ptr == '[') ? ']' : ')');
		    int l;
		    func = (op == '(');
		    for (ptr++, l = 1; *ptr && l; ptr++) {
			if (*ptr == op)
			    l++;
			if (*ptr == cp)
			    l--;
			if (*ptr == '\\' && ptr[1])
			    ptr++;
		    }
		}
		yylval = dupstrpfx(p, ptr - p);
		return (func ? FUNC : (cct ? CID : ID));
	    }
	    else if (cct) {
		yyval.u.l = poundgetfn(NULL);
		return NUM;
	    }
	    return EOI;
	}
}
示例#13
0
文件: lex.c 项目: AMDmi3/zsh
mod_export int
parse_subst_string(char *s)
{
    int c, l = strlen(s), err;
    char *ptr;
    enum lextok ctok;

    if (!*s || !strcmp(s, nulstring))
	return 0;
    zcontext_save();
    untokenize(s);
    inpush(dupstring(s), 0, NULL);
    strinbeg(0);
    lexbuf.len = 0;
    lexbuf.ptr = tokstr = s;
    lexbuf.siz = l + 1;
    c = hgetc();
    ctok = gettokstr(c, 1);
    err = errflag;
    strinend();
    inpop();
    DPUTS(cmdsp, "BUG: parse_subst_string: cmdstack not empty.");
    zcontext_restore();
    /* Keep any interrupt error status */
    errflag = err | (errflag & ERRFLAG_INT);
    if (ctok == LEXERR) {
	untokenize(s);
	return 1;
    }
#ifdef DEBUG
    /*
     * Historical note: we used to check here for olen (the value of lexbuf.len
     * before zcontext_restore()) == l, but that's not necessarily the case if
     * we stripped an RCQUOTE.
     */
    if (ctok != STRING || (errflag && !noerrs)) {
	fprintf(stderr, "Oops. Bug in parse_subst_string: %s\n",
		errflag ? "errflag" : "ctok != STRING");
	fflush(stderr);
	untokenize(s);
	return 1;
    }
#endif
    /* Check for $'...' quoting.  This needs special handling. */
    for (ptr = s; *ptr; )
    {
	if (*ptr == String && ptr[1] == Snull)
	{
	    char *t;
	    int len, tlen, diff;
	    t = getkeystring(ptr + 2, &len, GETKEYS_DOLLARS_QUOTE, NULL);
	    len += 2;
	    tlen = strlen(t);
	    diff = len - tlen;
	    /*
	     * Yuk.
	     * parse_subst_string() currently handles strings in-place.
	     * That's not so easy to fix without knowing whether
	     * additional memory should come off the heap or
	     * otherwise.  So we cheat by copying the unquoted string
	     * into place, unless it's too long.  That's not the
	     * normal case, but I'm worried there are pathological
	     * cases with converting metafied multibyte strings.
	     * If someone can prove there aren't I will be very happy.
	     */
	    if (diff < 0) {
		DPUTS(1, "$'...' subst too long: fix get_parse_string()");
		return 1;
	    }
	    memcpy(ptr, t, tlen);
	    ptr += tlen;
	    if (diff > 0) {
		char *dptr = ptr;
		char *sptr = ptr + diff;
		while ((*dptr++ = *sptr++))
		    ;
	    }
	} else
	    ptr++;
    }
    return 0;
}