parse_output.cc 3.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/* Copyright (C) 2004 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

unknown's avatar
unknown committed
17
#include "parse_output.h"
18

19
#include <my_global.h>
20
#include <my_sys.h>
unknown's avatar
unknown committed
21
#include <m_string.h>
22 23 24 25

#include <stdio.h>

#include "parse.h"
unknown's avatar
unknown committed
26
#include "portability.h"
27 28


29 30
void trim_space(const char **text, uint *word_len)
{
unknown's avatar
unknown committed
31
  const char *start= *text;
32 33 34 35 36
  while (*start != 0 && *start == ' ')
    start++;
  *text= start;

  int len= strlen(start);
unknown's avatar
unknown committed
37
  const char *end= start + len - 1;
38
  while (end > start && my_isspace(&my_charset_latin1, *end))
39 40
    end--;
  *word_len= (end - start)+1;
41 42
}

43 44
/*
  Parse output of the given command
45

46 47
  SYNOPSYS
    parse_output_and_get_value()
48

unknown's avatar
unknown committed
49 50 51 52 53 54
    command          the command to execue with popen.
    word             the word to look for (usually an option name)
    result           the buffer to store the next word (option value)
    input_buffer_len self-explanatory
    flag             this equals to GET_LINE if we want to get all the line after
                     the matched word and GET_VALUE otherwise.
55

56
  DESCRIPTION
57

58
    Parse output of the "command". Find the "word" and return the next one
unknown's avatar
unknown committed
59
    if flag is GET_VALUE. Return the rest of the parsed string otherwise.
unknown's avatar
unknown committed
60 61

  RETURN
unknown's avatar
unknown committed
62 63
    0 - ok, the word has been found
    1 - error occured or the word is not found
64
*/
65 66

int parse_output_and_get_value(const char *command, const char *word,
unknown's avatar
unknown committed
67 68
                               char *result, size_t input_buffer_len,
                               uint flag)
69 70
{
  FILE *output;
71
  uint wordlen;
72
  /* should be enough to store the string from the output */
73 74
  enum { MAX_LINE_LEN= 512 };
  char linebuf[MAX_LINE_LEN];
unknown's avatar
unknown committed
75
  int rc= 1;
76 77 78

  wordlen= strlen(word);

unknown's avatar
unknown committed
79 80 81 82 83
  /*
    Successful return of popen does not tell us whether the command has been
    executed successfully: if the command was not found, we'll get EOF
    when reading the output buffer below.
  */
84
  if (!(output= popen(command, "r")))
unknown's avatar
unknown committed
85
    goto err;
86 87 88 89 90 91 92

  /*
    We want fully buffered stream. We also want system to
    allocate appropriate buffer.
  */
  setvbuf(output, NULL, _IOFBF, 0);

93
  while (fgets(linebuf, sizeof(linebuf) - 1, output))
94
  {
unknown's avatar
unknown committed
95
    uint found_word_len= 0;
96 97 98 99 100
    char *linep= linebuf;

    linebuf[sizeof(linebuf) - 1]= '\0';        /* safety */

    /*
101
      Find the word(s) we are looking for in the line
102
    */
103
    if ((linep= strstr(linep, word)))
104 105
    {
      /*
106
        If we have found our word(s), then move linep past the word(s)
107
      */
108
      linep+= wordlen;
109
      if (flag & GET_VALUE)
110
      {
111
        trim_space((const char**) &linep, &found_word_len);
unknown's avatar
unknown committed
112
        if (input_buffer_len <= found_word_len)
113
          goto err;
unknown's avatar
unknown committed
114
        strmake(result, linep, found_word_len);
115
      }
unknown's avatar
unknown committed
116 117
      else         /* currently there are only two options */
        strmake(result, linep, input_buffer_len - 1);
unknown's avatar
unknown committed
118 119
      rc= 0;
      break;
120
    }
121 122
  }

unknown's avatar
unknown committed
123 124
  /* we are not interested in the termination status */
  pclose(output);
125

unknown's avatar
unknown committed
126
err:
unknown's avatar
unknown committed
127
  return rc;
128
}
129