static gchar * skip_string (gchar *buf) { if (buf && *buf == '\"') { buf = skip_quotes (buf, *buf); while (*buf) { if ((strncmp (buf, ", \"", 3) == 0) || (strncmp (buf, ", '", 3) == 0)) buf = skip_quotes (buf + 2, *(buf + 2)); else if (strncmp (buf, " <", 2) == 0) // take care of // <repeats buf = skip_delim (buf + 1, '<', '>'); else break; } // If the string is long then it's chopped and has ... after it. while (*buf && *buf == '.') buf++; } return buf; }
char *replace_env(char **env, char *cmd, int lret) { int size; char *str; size = replace_size_env(env, cmd, lret); size += replace_size_tilde(cmd, ft_getenv(env, "HOME")); str = ft_strnew(size + 1); size = 0; while (*cmd) { cmd = skip_quotes(cmd, &size); if (*cmd == '$') size += sub_replace_env(env, &cmd, &str[size], lret); else if (*cmd == '~') { size += replace_tilde(ft_getenv(env, "HOME"), &str[size]); cmd++; } else { str[size++] = *cmd; cmd++; } } str[size] = 0; return (str); }
static gchar * skip_token_end (gchar * buf) { if (buf) { switch (*buf) { case '"': return skip_string (buf); case '\'': return skip_quotes (buf, *buf); case '{': return skip_delim (buf, '{', '}'); case '<': return skip_delim (buf, '<', '>'); case '(': return skip_delim (buf, '(', ')'); } while (*buf && !isspace (*buf) && *buf != ',' && *buf != '}' && *buf != '=') buf++; } return buf; }
/* Returns contents of a string inside double quotes and parses escaped characters inside. Example: "\u006Corem ipsum" -> lorem ipsum */ static const char * get_processed_string(const char **string) { const char *string_start = *string; char *output, *processed_ptr, *unprocessed_ptr, current_char; unsigned int utf_val; skip_quotes(string); if (**string == '\0') { return NULL; } output = parson_strndup(string_start + 1, *string - string_start - 2); if (!output) { return NULL; } processed_ptr = unprocessed_ptr = output; while (*unprocessed_ptr) { current_char = *unprocessed_ptr; if (current_char == '\\') { unprocessed_ptr++; current_char = *unprocessed_ptr; switch (current_char) { case '\"': case '\\': case '/': break; case 'b': current_char = '\b'; break; case 'f': current_char = '\f'; break; case 'n': current_char = '\n'; break; case 'r': current_char = '\r'; break; case 't': current_char = '\t'; break; case 'u': unprocessed_ptr++; if (!is_utf((const unsigned char*)unprocessed_ptr) || sscanf(unprocessed_ptr, "%4x", &utf_val) == EOF) { parson_free(output); return NULL; } if (utf_val < 0x80) { current_char = utf_val; } else if (utf_val < 0x800) { *processed_ptr++ = (utf_val >> 6) | 0xC0; current_char = ((utf_val | 0x80) & 0xBF); } else { *processed_ptr++ = (utf_val >> 12) | 0xE0; *processed_ptr++ = (((utf_val >> 6) | 0x80) & 0xBF); current_char = ((utf_val | 0x80) & 0xBF); } unprocessed_ptr += 3; break; default: parson_free(output); return NULL; break; }
static gchar * skip_delim (gchar * buf, gchar open, gchar close) { if (buf && *buf == open) { buf++; while (*buf) { if (*buf == open) buf = skip_delim (buf, open, close); else if (*buf == close) return buf + 1; else if (*buf == '\"') buf = skip_string (buf); else if (*buf == '\'') buf = skip_quotes (buf, *buf); else if (*buf) buf++; } } return buf; }
static IAnjutaDebuggerDataType get_type (gchar **buf) { gchar *pos; if (!*buf || !*(*buf = skip_next_token_start (*buf))) return IANJUTA_DEBUGGER_UNKNOWN_TYPE; // A reference, probably from a parameter value. if (**buf == '@') return IANJUTA_DEBUGGER_REFERENCE_TYPE; // Structures and arrays - (but which one is which?) // {void (void)} 0x804a944 <__builtin_new+41> - this is a fn pointer // (void (*)(void)) 0x804a944 <f(E *, char)> - so is this - ugly!!! if (**buf == '{') { (*buf)++; if (**buf == '{') return IANJUTA_DEBUGGER_ARRAY_TYPE; if (strncmp (*buf, "<No data fields>}", 17) == 0) { (*buf) += 17; return IANJUTA_DEBUGGER_VALUE_TYPE; } pos = *buf; while (*pos) { switch (*pos) { case '=': return IANJUTA_DEBUGGER_STRUCT_TYPE; case '"': pos = skip_string (pos); break; case '\'': pos = skip_quotes (pos, '\''); break; case ',': if (*(pos - 1) == '}') { g_warning ("??????\n"); } return IANJUTA_DEBUGGER_ARRAY_TYPE; case '}': if (*(pos + 1) == ',' || *(pos + 1) == '\n' || !*(pos + 1)) return IANJUTA_DEBUGGER_ARRAY_TYPE; // Hmm a single element // array?? if (strncmp (pos + 1, " 0x", 3) == 0) return IANJUTA_DEBUGGER_POINTER_TYPE; // What about references? return IANJUTA_DEBUGGER_UNKNOWN_TYPE; // very odd? case '(': pos = skip_delim (pos, '(', ')'); break; case '<': pos = skip_delim (pos, '<', '>'); break; default: pos++; break; } } return IANJUTA_DEBUGGER_UNKNOWN_TYPE; } // some sort of address. We need to sort out if we have // a 0x888888 "this is a char*" type which we'll term a value // or whether we just have an address if (strncmp (*buf, "0x", 2) == 0) { pos = *buf; while (*pos) { if (!isspace (*pos)) pos++; else if (*(pos + 1) == '\"') return IANJUTA_DEBUGGER_VALUE_TYPE; else break; } return IANJUTA_DEBUGGER_POINTER_TYPE; } // Pointers and references - references are a bit odd // and cause GDB to fail to produce all the local data // if they haven't been initialised. but that's not our problem!! // (void (*)(void)) 0x804a944 <f(E *, char)> - this is a fn pointer if (**buf == '(') { pos = *buf; pos = skip_delim (pos, '(', ')'); pos -= 2; switch (*pos) { case ')': case '*': return IANJUTA_DEBUGGER_POINTER_TYPE; case '&': return IANJUTA_DEBUGGER_REFERENCE_TYPE; default: /* fix (char * const) - case */ while(*pos && (isalpha(*pos) || *pos == ' ')) --pos; switch(*pos) { case '*': return IANJUTA_DEBUGGER_POINTER_TYPE; case '&': return IANJUTA_DEBUGGER_REFERENCE_TYPE; default: return IANJUTA_DEBUGGER_UNKNOWN_TYPE; } } } pos = skip_token_value (*buf); if ((strncmp (pos, " = ", 3) == 0) || (*pos == '=')) return IANJUTA_DEBUGGER_NAME_TYPE; return IANJUTA_DEBUGGER_VALUE_TYPE; }