/**
* @file
* @brief GXL converting program
*/
/*************************************************************************
* Copyright (c) 2011 AT&T Intellectual Property
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors: Details at https://graphviz.org
*************************************************************************/
/*
* Written by Emden R. Gansner and Krishnam Pericherla
*/
#include "config.h"
#include
#include
#include
#include "convert.h"
#include "openFile.h"
#include
#include
#include
typedef enum { Unset, ToGV, ToGXL } mode;
static FILE *outFile;
static char *CmdName;
static char **Files;
static mode act = Unset;
#ifdef HAVE_EXPAT
static FILE *getFile(void)
{
FILE *rv = NULL;
static FILE *savef = NULL;
static int cnt = 0;
if (Files == NULL) {
if (cnt++ == 0) {
rv = stdin;
}
} else {
if (savef)
fclose(savef);
while (Files[cnt]) {
if ((rv = fopen(Files[cnt++], "r")) != 0)
break;
else
fprintf(stderr, "Can't open %s\n", Files[cnt - 1]);
}
}
savef = rv;
return rv;
}
#endif
static const char *use = "Usage: %s [-gd?] [-o] []\n\
-g : convert to GXL\n\
-d : convert to GV\n\
-o : output to (stdout)\n\
-? : usage\n";
static void usage(int v)
{
fprintf(stderr, use, CmdName);
graphviz_exit(v);
}
static char *cmdName(char *path)
{
char *sp;
sp = strrchr(path, '/');
if (sp)
sp++;
else
sp = path;
#ifdef _WIN32
char *sp2 = strrchr(sp, '\\');
if (sp2 != NULL)
sp = sp2 + 1;
#endif
return sp;
}
static void checkInput(void)
{
char *ep;
ep = strrchr(*Files, '.');
if (!ep)
return;
ep++;
if (strcmp(ep, "gv") == 0)
act = ToGXL;
else if (strcmp(ep, "dot") == 0)
act = ToGXL;
else if (strcmp(ep, "gxl") == 0)
act = ToGV;
}
static void setAction(void)
{
if (gv_tolower(CmdName[0]) == 'd')
act = ToGXL;
else if (gv_tolower(CmdName[0]) == 'g') {
if (gv_tolower(CmdName[1]) == 'v')
act = ToGXL;
else
act = ToGV;
}
else if (Files)
checkInput();
if (act == Unset) {
fprintf(stderr, "Cannot determine conversion type\n");
usage(1);
}
}
static void initargs(int argc, char **argv)
{
int c;
CmdName = cmdName(argv[0]);
opterr = 0;
while ((c = getopt(argc, argv, ":gdo:")) != -1) {
switch (c) {
case 'd':
act = ToGV;
break;
case 'g':
act = ToGXL;
break;
case 'o':
if (outFile != NULL)
fclose(outFile);
outFile = openFile(CmdName, optarg, "w");
break;
case ':':
fprintf(stderr, "%s: option -%c missing argument\n", CmdName, optopt);
break;
case '?':
if (optopt == '?')
usage(0);
else {
fprintf(stderr, "%s: option -%c unrecognized\n", CmdName,
optopt);
graphviz_exit(1);
}
break;
default:
fprintf(stderr, "cvtgxl: unexpected error\n");
graphviz_exit(EXIT_FAILURE);
}
}
argv += optind;
argc -= optind;
if (argc > 0)
Files = argv;
if (!outFile)
outFile = stdout;
if (act == Unset)
setAction();
}
int main(int argc, char **argv)
{
Agraph_t *G;
Agraph_t *prev = 0;
initargs(argc, argv);
if (act == ToGXL) {
ingraph_state ig;
newIngraph(&ig, Files);
while ((G = nextGraph(&ig))) {
if (prev)
agclose(prev);
prev = G;
gv_to_gxl(G, outFile);
fflush(outFile);
}
} else {
#ifdef HAVE_EXPAT
FILE *inFile;
while ((inFile = getFile())) {
while ((G = gxl_to_gv(inFile))) {
if (prev)
agclose(prev);
prev = G;
agwrite(G, outFile);
fflush(outFile);
}
}
#else
fputs("cvtgxl: not configured for conversion from GXL to GV\n",
stderr);
graphviz_exit(1);
#endif
}
graphviz_exit(0);
}