Commit bd4c432d authored by hark's avatar hark
Browse files

autodetect width and height

parent 41b4f75f
......@@ -24,7 +24,7 @@ c-player-0.10 : c-player.c
c-player-debug : c-player.c
gcc -D TT -DTESTING -DGTK -DGST1 -g c-player.c wraps.c playlist.c snowbin.c teebin.c -o c-player-debug `pkg-config --cflags --libs gtk+-2.0 gstreamer-1.0 gstreamer-pbutils-1.0 gstreamer-video-1.0` $(CFLAGS)
c-player : c-player.c
c-player : c-player.c snowbin.c playlist.c teebin.c wraps.c
gcc -DGTK -DGST1 -g c-player.c wraps.c playlist.c snowbin.c teebin.c -o c-player `pkg-config --cflags --libs gtk+-2.0 gstreamer-1.0 gstreamer-pbutils-1.0 gstreamer-video-1.0` $(CFLAGS)
c-player-cli : c-player.c
......
......@@ -30,7 +30,6 @@
static const char *playuri = NULL;
static char *feedname = NULL;
static int preview = 0;
// CustomData data;
static GstStateChangeReturn ret;
static GstBus *bus;
// snowbin or auto
......@@ -82,7 +81,7 @@ static gpointer thread_time_func( gpointer data )
#ifdef GTK
static void
realize_cb (GtkWidget * widget, CustomData * data)
realize_cb (GtkWidget * widget, PlayerData * data)
{
GdkWindow *window = gtk_widget_get_window (widget);
static guintptr window_handle;
......@@ -114,7 +113,7 @@ realize_cb (GtkWidget * widget, CustomData * data)
/* This function is called when the PLAY button is clicked */
#ifdef GTK
static void
play_cb (GtkButton * button, CustomData * data)
play_cb (GtkButton * button, PlayerData * data)
{
gst_element_set_state (data->playbin2, GST_STATE_PLAYING);
......@@ -123,7 +122,7 @@ play_cb (GtkButton * button, CustomData * data)
/* This function is called when the PAUSE button is clicked */
static void
pause_cb (GtkButton * button, CustomData * data)
pause_cb (GtkButton * button, PlayerData * data)
{
gst_element_set_state (data->playbin2, GST_STATE_PAUSED);
......@@ -132,7 +131,7 @@ pause_cb (GtkButton * button, CustomData * data)
/* This function is called when the STOP button is clicked */
static void
stop_cb (GtkButton * button, CustomData * data)
stop_cb (GtkButton * button, PlayerData * data)
{
gst_element_set_state (data->playbin2, GST_STATE_READY);
}
......@@ -142,9 +141,9 @@ stop_cb (GtkButton * button, CustomData * data)
load_uri (const gchar * uri)
{
// this would stop playback, so don't do that
//gst_element_set_state (globalData.playbin2, GST_STATE_READY);
//gst_element_set_state (playerData.playbin2, GST_STATE_READY);
// GstStateChangeReturn ret;
g_object_set (globalData.playbin2, "uri", uri, NULL);
g_object_set (pData->playbin2, "uri", uri, NULL);
#ifdef GTK
markup =
......@@ -152,12 +151,12 @@ load_uri (const gchar * uri)
("<span foreground=\"red\" size=\"x-large\">%s</span>", uri);
gtk_label_set_markup (GTK_LABEL (loaded_label), markup);
#endif
// gst_element_set_state (globalData.playbin2, GST_STATE_PLAYING);
// gst_element_set_state (pData->playbin2, GST_STATE_PLAYING);
}
#ifdef GTK
static void
preview_cb (GtkCheckButton * preview_check, CustomData * data)
preview_cb (GtkCheckButton * preview_check, PlayerData * data)
{
while (TRUE)
{
......@@ -165,15 +164,15 @@ preview_cb (GtkCheckButton * preview_check, CustomData * data)
{
g_print ("turning on preview checkcb \n");
teebin_preview_on(data);
/* gst_element_set_state (globalData.playbin2, GST_STATE_NULL);
/* gst_element_set_state (pData->playbin2, GST_STATE_NULL);
GstElement *videosink, *audiosink;
videosink = gst_element_factory_make ("xvimagesink", "xvimagesink");
audiosink =
gst_element_factory_make ("autoaudiosink", "autoaudiosink");
g_object_set (globalData.playbin2, "video-sink", videosink, NULL);
g_object_set (globalData.playbin2, "audio-sink", audiosink, NULL);
gst_element_set_state (globalData.playbin2, GST_STATE_PLAYING);
g_object_set (pData->playbin2, "video-sink", videosink, NULL);
g_object_set (pData->playbin2, "audio-sink", audiosink, NULL);
gst_element_set_state (pData->playbin2, GST_STATE_PLAYING);
*/
preview = 1;
break;
......@@ -205,7 +204,7 @@ preview_cb (GtkCheckButton * preview_check, CustomData * data)
/* This function is called when the main window is closed */
#ifdef GTK
static void
delete_event_cb (GtkWidget * widget, GdkEvent * event, CustomData * data)
delete_event_cb (GtkWidget * widget, GdkEvent * event, PlayerData * data)
{
stop_cb (NULL, data);
gtk_main_quit ();
......@@ -215,7 +214,7 @@ delete_event_cb (GtkWidget * widget, GdkEvent * event, CustomData * data)
* rescaling, etc). GStreamer takes care of this in the PAUSED and PLAYING states, otherwise,
* we simply draw a black rectangle to avoid garbage showing up. */
static gboolean
expose_cb (GtkWidget * widget, GdkEventExpose * event, CustomData * data)
expose_cb (GtkWidget * widget, GdkEventExpose * event, PlayerData * data)
{
if (data->state < GST_STATE_PAUSED)
......@@ -244,7 +243,7 @@ expose_cb (GtkWidget * widget, GdkEventExpose * event, CustomData * data)
/* This function is called when the slider changes its position. We perform a seek to the
* new position here. */
static void
slider_cb (GtkRange * range, CustomData * data)
slider_cb (GtkRange * range, PlayerData * data)
{
gdouble value = gtk_range_get_value (GTK_RANGE (data->slider));
gst_element_seek_simple (data->playbin2, GST_FORMAT_TIME,
......@@ -256,7 +255,7 @@ slider_cb (GtkRange * range, CustomData * data)
#ifdef GTK
/* This creates all the GTK+ widgets that compose our application, and registers the callbacks */
static void
create_ui (CustomData * data)
create_ui (PlayerData * data)
{
static GtkWidget *main_window; /* The uppermost window, containing all other windows */
......@@ -398,7 +397,7 @@ thread_time = g_thread_create( thread_time_func, (gpointer)label_time, FALSE, &e
#ifdef GTK
/* This function is called periodically to refresh the GUI */
static int
refresh_ui (CustomData * data)
refresh_ui (PlayerData * data)
{
GstFormat fmt = GST_FORMAT_TIME;
gint64 current = -1;
......@@ -469,18 +468,18 @@ refresh_ui (CustomData * data)
player_reset_and_play ()
{
/* stop playing */
gst_element_set_state (globalData.playbin2, GST_STATE_READY);
gst_element_set_state (pData->playbin2, GST_STATE_READY);
printf("current uri: %s", playlist_get_current());
load_uri(playlist_get_current());
// static int ret;
/* Start playing */
ret = gst_element_set_state (globalData.playbin2, GST_STATE_PLAYING);
ret = gst_element_set_state (pData->playbin2, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE)
{
g_printerr ("state change failure in player_reset_and_play\n");
// gst_object_unref (globalData.playbin2);
// gst_object_unref (pData->playbin2);
// return -1;
return 1;
}
......@@ -490,7 +489,7 @@ player_reset_and_play ()
/* This function is called when new metadata is discovered in the stream */
static void
tags_cb (GstElement * playbin2, gint stream, CustomData * data)
tags_cb (GstElement * playbin2, gint stream, PlayerData * data)
{
/* We are possibly in a GStreamer working thread, so we notify the main
* thread of this event through a message in the bus */
......@@ -508,7 +507,7 @@ tags_cb (GstElement * playbin2, gint stream, CustomData * data)
/* This function is called when an error message is posted on the bus */
static void
error_cb (GstBus * bus, GstMessage * msg, CustomData * data)
error_cb (GstBus * bus, GstMessage * msg, PlayerData * data)
{
GError *err;
gchar *debug_info;
......@@ -530,7 +529,7 @@ error_cb (GstBus * bus, GstMessage * msg, CustomData * data)
* next item in playlist will be loaded now
* and something should flash*/
static void
aeos_cb (GstBus * bus, GstMessage * msg, CustomData * data)
aeos_cb (GstBus * bus, GstMessage * msg, PlayerData * data)
{
g_print ("Almost finished.\n");
......@@ -541,7 +540,7 @@ aeos_cb (GstBus * bus, GstMessage * msg, CustomData * data)
/* this function is called after source element is setup */
static void
source_cb (GstBus * bus, GstMessage * msg, CustomData * data)
source_cb (GstBus * bus, GstMessage * msg, PlayerData * data)
{
g_print ("Source setup.\n");
......@@ -553,7 +552,7 @@ source_cb (GstBus * bus, GstMessage * msg, CustomData * data)
/* This function is called when an End-Of-Stream message is posted on the bus.
* We just set the pipeline to READY (which stops playback) */
static void
eos_cb (GstBus * bus, GstMessage * msg, CustomData * data)
eos_cb (GstBus * bus, GstMessage * msg, PlayerData * data)
{
g_print ("End-Of-Stream reached.\n");
gst_element_set_state (data->playbin2, GST_STATE_READY);
......@@ -569,7 +568,7 @@ eos_cb (GstBus * bus, GstMessage * msg, CustomData * data)
/* This function is called when the pipeline changes states. We use it to
* keep track of the current state. */
static void
state_changed_cb (GstBus * bus, GstMessage * msg, CustomData * data)
state_changed_cb (GstBus * bus, GstMessage * msg, PlayerData * data)
{
GstState old_state, new_state, pending_state;
gst_message_parse_state_changed (msg, &old_state, &new_state,
......@@ -686,7 +685,7 @@ state_changed_cb (GstBus * bus, GstMessage * msg, CustomData * data)
/* Extract metadata from all the streams and write it to the text widget in the GUI */
static void
analyze_streams (CustomData * data)
analyze_streams (PlayerData * data)
{
gint i;
GstTagList *tags;
......@@ -811,7 +810,7 @@ analyze_streams (CustomData * data)
/* This function is called when an "application" message is posted on the bus.
* Here we retrieve the message posted by the tags_cb callback */
static void
application_cb (GstBus * bus, GstMessage * msg, CustomData * data)
application_cb (GstBus * bus, GstMessage * msg, PlayerData * data)
{
/* with gst1
* player-0.10.c: In function ‘application_cb’:
......@@ -837,15 +836,14 @@ static void init_media()
/* Initialize GStreamer */
gst_init (NULL, NULL);
/* Initialize our data structure */
memset (&globalData, 0, sizeof (globalData));
globalData.duration = GST_CLOCK_TIME_NONE;
pData->duration = GST_CLOCK_TIME_NONE;
/* Create the elements */
#ifdef GST1
globalData.playbin2 = gst_element_factory_make ("playbin", "playbin2");
pData->playbin2 = gst_element_factory_make ("playbin", "playbin2");
#else
globalData.playbin2 = gst_element_factory_make ("playbin2", "playbin2");
pData->playbin2 = gst_element_factory_make ("playbin2", "playbin2");
#endif
......@@ -859,8 +857,8 @@ static void init_media()
xvimagesink = gst_element_factory_make("xvimagesink", "xvimagesink");
gst_element_factory_make("xvimagesink", "xvimagesink");
/*set snowvideobin as sink */
g_object_set (globalData.playbin2, "video-sink",
create_teebin(xvimagesink, get_snowvideobin(feedname)), NULL);
g_object_set (pData->playbin2, "video-sink",
create_teebin(xvimagesink, get_snowvideobin(pData->snow)), NULL);
// g_object_set (globalData.playbin2, "video-sink",
// get_snowvideobin(feedname), NULL);
......@@ -868,8 +866,8 @@ static void init_media()
// create_teebin(xvimagesink, create_rtmpbin()), NULL);
/*set snowaudiobin as sink */
g_object_set (globalData.playbin2, "audio-sink",
get_snowaudiobin (feedname), NULL);
g_object_set (pData->playbin2, "audio-sink",
get_snowaudiobin (pData->snow), NULL);
//audiosink = gst_element_factory_make ("jackaudiosink", "jackaudiosink");
//g_object_set (globalData.playbin2, "audio-sink", audiosink, NULL);
//g_object_set (audiosink, "port-pattern", feedname, NULL);
......@@ -884,8 +882,8 @@ static void init_media()
videosink = gst_element_factory_make ("xvimagesink", "xvimagesink");
audiosink = gst_element_factory_make ("autoaudiosink", "autoaudiosink");
g_object_set (globalData.playbin2, "video-sink", videosink, NULL);
g_object_set (globalData.playbin2, "audio-sink", audiosink, NULL);
g_object_set (pData->playbin2, "video-sink", videosink, NULL);
g_object_set (pData->playbin2, "audio-sink", audiosink, NULL);
}
......@@ -893,7 +891,7 @@ static void init_media()
g_print (" SNOWBIN is not defined (port it to gst1.0)");
#endif
if (!globalData.playbin2)
if (!pData->playbin2)
{
g_printerr ("Not all elements could be created.\n");
//return -1;
......@@ -903,30 +901,30 @@ static void init_media()
//g_object_set (globalData.playbin2, "uri", "http://docs.gstreamer.com/media/sintel_trailer-480p.webm", NULL);
/* Connect to interesting signals in playbin2 */
g_signal_connect (G_OBJECT (globalData.playbin2), "video-tags-changed",
(GCallback) tags_cb, &globalData);
g_signal_connect (G_OBJECT (globalData.playbin2), "audio-tags-changed",
(GCallback) tags_cb, &globalData);
g_signal_connect (G_OBJECT (globalData.playbin2), "text-tags-changed",
(GCallback) tags_cb, &globalData);
g_signal_connect (G_OBJECT (globalData.playbin2), "about-to-finish",
(GCallback) aeos_cb, &globalData);
g_signal_connect (G_OBJECT (globalData.playbin2), "source-setup",
(GCallback) source_cb, &globalData);
g_signal_connect (G_OBJECT (pData->playbin2), "video-tags-changed",
(GCallback) tags_cb, pData);
g_signal_connect (G_OBJECT (pData->playbin2), "audio-tags-changed",
(GCallback) tags_cb, pData);
g_signal_connect (G_OBJECT (pData->playbin2), "text-tags-changed",
(GCallback) tags_cb, pData);
g_signal_connect (G_OBJECT (pData->playbin2), "about-to-finish",
(GCallback) aeos_cb, pData);
g_signal_connect (G_OBJECT (pData->playbin2), "source-setup",
(GCallback) source_cb, pData);
/* Instruct the bus to emit signals for each received message, and connect to the interesting signals */
bus = gst_element_get_bus (globalData.playbin2);
bus = gst_element_get_bus (pData->playbin2);
gst_bus_add_signal_watch (bus);
g_signal_connect (G_OBJECT (bus), "message::error", (GCallback) error_cb,
&globalData);
pData);
g_signal_connect (G_OBJECT (bus), "message::eos", (GCallback) eos_cb,
&globalData);
pData);
g_signal_connect (G_OBJECT (bus), "message::state-changed",
(GCallback) state_changed_cb, &globalData);
(GCallback) state_changed_cb, pData);
g_signal_connect (G_OBJECT (bus), "message::application",
(GCallback) application_cb, &globalData);
(GCallback) application_cb, pData);
g_signal_connect (G_OBJECT (bus), "message::about-to-finish",
(GCallback) application_cb, &globalData);
(GCallback) application_cb, pData);
gst_object_unref (bus);
......@@ -970,6 +968,12 @@ main (int argc, char *argv[])
} //while
/* Initialize our data structure */
//memset (&playerData, 0, sizeof (globalData));
pData = (PlayerData*)malloc(sizeof(struct PlayerData));
#ifdef GTK
#ifdef TT
if( ! g_thread_supported() )
......@@ -981,21 +985,25 @@ main (int argc, char *argv[])
/* Initialize GTK */
gtk_init (&argc, &argv);
#endif
/* initialize snowbin */
snowbin_init_snowData(pData);
/* initialize gstreamer */
init_media();
/* Create the GUI */
#ifdef GTK
create_ui (&globalData);
create_ui (pData);
#endif
/* Register a function that GLib will call every second */
#ifdef GTK
g_timeout_add_seconds (1, (GSourceFunc)refresh_ui, &globalData);
g_timeout_add_seconds (1, (GSourceFunc)refresh_ui, pData);
#endif
/* register a function that will check all items in the playlist for availablitity */
// g_timeout_add_seconds (15, (GsourceFunc)playlist_refresh, &globalData);
// g_timeout_add_seconds (15, (GsourceFunc)playlist_refresh, &pData);
/* Start the GTK main loop. We will not regain control until gtk_main_quit is called. */
#ifdef GTK
......@@ -1008,7 +1016,7 @@ init_media();
printf("using this without gtk is on the todo list");
#endif
/* Free resources */
gst_element_set_state (globalData.playbin2, GST_STATE_NULL);
gst_object_unref (globalData.playbin2);
gst_element_set_state (pData->playbin2, GST_STATE_NULL);
gst_object_unref (pData->playbin2);
return 0;
}
......@@ -31,7 +31,8 @@
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <regex.h>
#include "switchs.h"
//glib stuff
//#include <glib.h>
//#include <glib-2.0/glib/gprintf.h>
......@@ -118,7 +119,8 @@ GtkWidget *loaded_label;
gboolean playabool;
/* Structure to contain all our information, so we can pass it around */
typedef struct _CustomData{
typedef struct PlayerData PlayerData;
struct PlayerData{
GstElement *playbin2; /* Our one and only pipeline */
......@@ -130,14 +132,14 @@ typedef struct _CustomData{
GstState state; /* Current state of the pipeline */
gint64 duration; /* Duration of the clip, in nanoseconds */
} CustomData;
snowData *snow;
};
CustomData globalData;
//CustomData globalData;
CustomData *data;
PlayerData *pData;
//CustomData *data;
GtkWidget *playlist_view;
GtkWidget *playlist_box;
#endif
......@@ -8,8 +8,8 @@ port=9999
ip=127.0.0.1
# Set video feed
feed_id=1
audio_feed_id=1
feed_id=$1
audio_feed_id=$1
# Check for SM variable and the snowmix and gstreamer settings
if [ X$SM = X -o ! -f $SM/scripts/gstreamer-settings -o ! -f $SM/scripts/snowmix-settings ] ; then
......
......@@ -32,6 +32,11 @@ GtkWidget *file_window, *uri_entrybox;
int loop_current = 0;
int loop_all = 0;
// to change
PlayerData *data;
/*playlist stuff */
GtkListStore *playlist_store;
......@@ -263,7 +268,7 @@ update_playlist (const gchar * uri, const GstTagList * tags,
* one of the URIs we provided.*/
static void
on_discovered_cb (GstDiscoverer * discoverer, GstDiscovererInfo * info,
GError * err, CustomData * data)
GError * err, PlayerData * data)
{
GstDiscovererResult result;
const gchar *uri;
......@@ -305,7 +310,7 @@ on_discovered_cb (GstDiscoverer * discoverer, GstDiscovererInfo * info,
}
static void
on_discover_finished_cb (CustomData * data)
on_discover_finished_cb (PlayerData * data)
{
//printf ("discover finished \n");
}
......@@ -314,9 +319,9 @@ static void
discoverer_init ()
{
/* Instantiate the Discoverer */
globalData.discoverer = gst_discoverer_new (5 * GST_SECOND, &err);
pData->discoverer = gst_discoverer_new (5 * GST_SECOND, &err);
if (!globalData.discoverer)
if (!pData->discoverer)
{
g_print ("Error creating discoverer instance: %s\n", err->message);
g_clear_error (&err);
......@@ -324,13 +329,13 @@ discoverer_init ()
// return -1;
}
/* Connect to the interesting signals */
g_signal_connect (globalData.discoverer, "discovered",
G_CALLBACK (on_discovered_cb), &globalData);
g_signal_connect (globalData.discoverer, "finished",
G_CALLBACK (on_discover_finished_cb), &globalData);
g_signal_connect (pData->discoverer, "discovered",
G_CALLBACK (on_discovered_cb), pData);
g_signal_connect (pData->discoverer, "finished",
G_CALLBACK (on_discover_finished_cb), pData);
/* Start the discoverer process (nothing to do yet) */
gst_discoverer_start (globalData.discoverer);
gst_discoverer_start (pData->discoverer);
}
......@@ -339,10 +344,10 @@ discover_uri (const gchar * uri)
{
//g_print ("discovering: %s \n", uri);
if (!gst_discoverer_discover_uri_async (globalData.discoverer, uri))
if (!gst_discoverer_discover_uri_async (pData->discoverer, uri))
{
g_print ("Failed to start discovering URI \n");
g_object_unref (globalData.discoverer);
g_object_unref (pData->discoverer);
// return -1;
}
......@@ -540,7 +545,7 @@ playlist_selection_changed_cb (GtkTreeSelection * selection, gpointer data)
}
static void
refresh_ui (CustomData * data)
refresh_ui (PlayerData * data)
{
g_print ("refreshing playlist, recheck non playable streams here \n");
}
......@@ -680,7 +685,7 @@ delete_cb ()
/*add item to playlist */
static void
add_cb (GtkButton * button, CustomData * data)
add_cb (GtkButton * button, PlayerData * data)
{
printf ("add_cb \n");
playlist_add_item (gtk_entry_get_text (GTK_ENTRY (uri_entrybox)));
......@@ -690,7 +695,7 @@ add_cb (GtkButton * button, CustomData * data)
/* This function is called when the OPEN button is clicked */
static void
open_cb (GtkButton * button, CustomData * data)
open_cb (GtkButton * button, PlayerData * data)
{
printf ("open_cb: not doing anything, fix me! \n");
......@@ -708,13 +713,13 @@ open_cb (GtkButton * button, CustomData * data)
gtk_widget_show(video_window);
}
g_object_set (globalData.playbin2, "current-audio", 0, NULL);
g_object_set (pData->playbin2, "current-audio", 0, NULL);
*/
}
/* This function is called when the OPEN uri button is clicked */
static void
open_uri_cb (GtkButton * button, CustomData * data)
open_uri_cb (GtkButton * button, PlayerData * data)
{
// printf ("open_uri_cb: not doing anything, fix me! \n");
char *playuri;
......@@ -731,7 +736,7 @@ open_uri_cb (GtkButton * button, CustomData * data)
/* This function is called when the loop checbutton is toggled, this should be done by playlist */
static void
loop_current_cb (GtkCheckButton * loop_current_check, CustomData * data)
loop_current_cb (GtkCheckButton * loop_current_check, PlayerData * data)
{
while (TRUE)
{
......@@ -752,7 +757,8 @@ loop_current_cb (GtkCheckButton * loop_current_check, CustomData * data)
static void
playlist_load_file (char * file) {
printf("playlist_load_file not doing anything");
// printf("playlist_load_file not doing anything");
return 0;
}
static void
......
......@@ -33,4 +33,4 @@ extern gchar *playlist_get_next ();
extern gboolean playlist_refresh (CustomData * data);
extern gboolean playlist_refresh (PlayerData * data);
......@@ -25,6 +25,146 @@
#include "common.h"
#endif
int
get_vars (snowMixer *mixer, snowFeed *feed)
{
FILE *fp;
char line[1035];
regex_t regex;
int retsnow;
char msgbuf[100];
size_t nmatch = 3;
regmatch_t pmatch[3];
char key[100], value[100];
/* Compile regular expression */
// retsnow = regcomp(&regex, "^Snowmix[[:print:]]*", 0);
// retsnow = regcomp(&regex, "^[_[:alnum:]]*[[:punct:]][[:blank:]][[:alnum:]]*", REG_EXTENDED);
retsnow = regcomp(&regex, "^\([_[:alnum:]]*\)[[:punct:]][[:blank:]]\([[:print:]]*\)", REG_EXTENDED);
if (retsnow) {
fprintf(stderr, "Could not compile regex\n");
exit(1);
}
/* Open the command for reading. */
fp = popen("./getvars.sh 2", "r");
if (fp == NULL) {
printf("Failed to run command\n" );
exit(1);
}
while (fgets(line, sizeof(line)-1, fp) != NULL) {
retsnow = regexec(&regex, line, nmatch, pmatch, 0);
if (!retsnow) {
//puts("Match");
// printf("%s m1: %s m2: %s m3: %s", line, pmatch[0], pmatch[1], pmatch[2]);
int n = 0;
/*
printf("With the whole expression, "
"a matched substring \"%.*s\" is found at position %d to %d.\n",
pmatch[n].rm_eo - pmatch[n].rm_so, &line[pmatch[n].rm_so],
pmatch[n].rm_so, pmatch[n].rm_eo - 1);
*/
n = 1;
// snprintf(key, sizeof(&key), "%.*s",pmatch[n].rm_eo - pmatch[n].rm_so, &line[pmatch[n].rm_so],pmatch[n].rm_so, pmatch[n].rm_eo - 1);
// | lenght | start? |
snprintf(key, sizeof(key), "%.*s",pmatch[n].rm_eo - pmatch[n].rm_so, &line[pmatch[n].rm_so]);
n = 2;
// snprintf(value, sizeof(&value), "%.*s",pmatch[n].rm_eo - pmatch[n].rm_so, &line[pmatch[n].rm_so],pmatch[n].rm_so, pmatch[n].rm_eo - 1);
snprintf(value, sizeof(value), "%.*s",pmatch[n].rm_eo - pmatch[n].rm_so, &line[pmatch[n].rm_so]);
// printf("keyvalue: %s %s \n ", key, value);
switchs(key){