/*
* Maketool - GTK-based front end for gmake
* Copyright (c) 1999-2003 Greg Banks
*
* 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
*/
#include "maketool.h"
#if HAVE_SUN_MAKE
#include "util.h"
#if HAVE_REGCOMP
#include <regex.h> /* POSIX regular expression fns */
#else
#error Why are you even bothering to compile with POSIX regular expressions?
#endif
CVSID("$Id: sunmake.c,v 1.2 2003/09/01 13:23:34 gnb Exp $");
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
static void
sunmake_makefile_flags(estring *e)
{
if (prefs.makefile != 0)
{
estring_append_string(e, "-f ");
estring_append_string(e, prefs.makefile);
}
}
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
static void
sunmake_parallel_flags(estring *e)
{
/* Sun make does not implement parallelism */
}
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
static void
sunmake_keep_going_flags(estring *e)
{
if (prefs.keep_going)
estring_append_string(e, "-k");
}
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
static void
sunmake_dryrun_flags(estring *e)
{
if (prefs.dryrun)
estring_append_string(e, "-n");
}
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
static void
sunmake_version_flags(estring *e)
{
estring_append_string(e, "-V"); /* TODO: check */
}
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
static void
sunmake_list_targets_flags(estring *e)
{
estring_append_string(e, "-n -p");
}
typedef struct
{
Task task;
#define NUM_ERROR_LINES 16
int nlines;
estring error_buf; /* first NUM_ERROR_LINES of output */
GPtrArray *targets;
regex_t target_re;
} SunmakeListTargetsTask;
static void
sunmake_list_targets_reap(Task *task)
{
SunmakeListTargetsTask *ltt = (SunmakeListTargetsTask *)task;
if (!task_is_successful(task))
{
/* Report error to user */
list_targets_error(ltt->error_buf.data);
}
else
{
/* Set all the targets */
set_targets(ltt->targets->len, (char **)ltt->targets->pdata);
/* set_targets() has taken over the array and strings, so forget them */
g_ptr_array_free(ltt->targets, /*free_seg*/FALSE);
ltt->targets = 0;
}
}
/*
* Task has TASK_LINEMODE flag, so the input function gets
* called once per line. Unlike several UNIX awk implementations
* we have no line length limit.
*/
static void
sunmake_list_targets_input(Task *task, int len, const char *buf)
{
SunmakeListTargetsTask *ltt = (SunmakeListTargetsTask *)task;
regmatch_t match[2];
/*
* Save the first few lines of the output to a buffer
* in case they represent an error message.
*/
if (++ltt->nlines <= NUM_ERROR_LINES)
{
estring_append_chars(<t->error_buf, buf, len);
estring_append_char(<t->error_buf, '\n');
}
/* Match line against the target regular expression. */
if (regexec(<t->target_re, buf, /*nmatches*/2, match, 0) == 0)
{
/* extract target name from line...steal the buffer temporarily */
char *targ, oldc;
int len;
targ = (char *)buf+match[1].rm_so;
len = match[1].rm_eo - match[1].rm_so;
oldc = targ[len];
targ[len] = '\0';
if (filter_target(targ))
g_ptr_array_add(ltt->targets, g_strdup(targ));
targ[len] = oldc;
}
}
static void
sunmake_list_targets_destroy(Task *task)
{
SunmakeListTargetsTask *ltt = (SunmakeListTargetsTask *)task;
if (ltt->targets != 0)
{
int i;
for (i = 0 ; i < ltt->targets->len ; i++)
g_free(ltt->targets->pdata[i]);
g_ptr_array_free(ltt->targets, /*free_seg*/TRUE);
}
regfree(<t->target_re);
estring_free(<t->error_buf);
}
static TaskOps sunmake_list_targets_ops =
{
0, /* start */
sunmake_list_targets_input, /* input */
sunmake_list_targets_reap, /* reap */
sunmake_list_targets_destroy /* destroy */
};
static Task *
sunmake_list_targets_task(char *cmd)
{
SunmakeListTargetsTask *ltt = g_new(SunmakeListTargetsTask, 1);
int err;
ltt->targets = g_ptr_array_new();
err = regcomp(<t->target_re, "^([^#:=! \t]+):", REG_EXTENDED);
assert(err == 0);
ltt->nlines = 0;
estring_init(<t->error_buf);
return task_create(
(Task *)ltt,
/*cmd*/strdup("cat sunmake.txt"),
prefs.var_environment,
&sunmake_list_targets_ops,
TASK_LINEMODE);
}
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
static const char * const sunmake_makefiles[] =
{
"Makefile",
"makefile",
0
};
const MakeProgram makeprog_sun_make =
{
"sunmake",
"make",
N_("Sun make"),
/*logo_xpm*/0,
sunmake_makefiles,
sunmake_makefile_flags,
sunmake_parallel_flags,
sunmake_keep_going_flags,
sunmake_dryrun_flags,
sunmake_version_flags,
sunmake_list_targets_flags,
sunmake_list_targets_task
};
#endif /* HAVE_SUN_MAKE */
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
/*END*/
syntax highlighted by Code2HTML, v. 0.9.1