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); }
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); }
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); }
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); }
/** 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); }
/** 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); }
/** 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); }
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); }
/** 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); }
/** 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 */ }
/** 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; }
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; } }
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; }