dpe.c 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874
  1. /*
  2. * Copyright 2021
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. *
  17. * These are the four essential freedoms with GNU GPL software:
  18. * 1: freedom to run the program, for any purpose
  19. * 2: freedom to study how the program works, and change it to make it do what you wish
  20. * 3: freedom to redistribute copies to help your Free Software friends
  21. * 4: freedom to distribute copies of your modified versions to your Free Software friends
  22. * , ,
  23. * / \
  24. * ((__-^^-,-^^-__))
  25. * `-_---' `---_-'
  26. * `--|o` 'o|--'
  27. * \ ` /
  28. * ): :(
  29. * :o_o:
  30. * "-"
  31. *
  32. * SPDX-License-Identifier: GPL-3.0+
  33. * License-Filename: LICENSE
  34. */
  35. /* edge attributes:
  36. *
  37. */
  38. #include "config.h"
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <string.h>
  42. #include <math.h>
  43. #include <zlib.h>
  44. #include "splay-tree.h"
  45. #include "dp.h"
  46. #include "dpe.h"
  47. #include "dpus.h"
  48. #include "dpmisc.h"
  49. #include "dpcolor.h"
  50. #include "lex.yy.h"
  51. #include "dpmem.h"
  52. /* edge[] attribute to check
  53. * URL arrowhead arrowsize arrowtail color colorscheme comment constraint
  54. * decorate dir edgeURL edgehref edgetarget edgetooltip fontcolor fontname
  55. * fontsize headURL head_lp headclip headhref headlabel headport headtarget
  56. * headtooltip href id label labelURL labelangle labeldistance labelfloat
  57. * labelfontcolor labelfontname labelfontsize labelhref labeltarget
  58. * labeltooltip layer len lhead lp ltail minlen nojustify penwidth
  59. * pos samehead sametail showboxes style tailURL tail_lp tailclip tailhref
  60. * taillabel tailport tailtarget tailtooltip target tooltip weight xlabel xlp
  61. */
  62. void dp_do_eattr(char *l, char *r)
  63. {
  64. int tmpi = 0;
  65. int cc = 0;
  66. struct dpedge *res = NULL;
  67. struct dpnum *num = NULL;
  68. struct dpcolor *colornum = NULL;
  69. struct dparrow *arrownum = NULL;
  70. struct dpbool *boolnum = 0;
  71. struct dpdir *dirnum = NULL;
  72. struct dppoint *pointnum = NULL;
  73. struct dpstyle *stylenum = NULL;
  74. if (dp_cclass == DP_TEDGE) {
  75. res = dp_curedge;
  76. } else if (dp_cclass == DP_TEDGEDEF) {
  77. res = dp_curgraph->defedge;
  78. } else {
  79. printf("dot %s(): shouldnothappen dp_cclass=%d\n", __func__, dp_cclass);
  80. return;
  81. }
  82. /* switch on first char */
  83. cc = (*l);
  84. switch (cc) {
  85. /* URL */
  86. case 'U':
  87. if (strcmp(l, "URL") == 0) {
  88. if (r) {
  89. if (strlen(r)) {
  90. res->url = r;
  91. } else {
  92. res->url = NULL;
  93. }
  94. res->bitflags0.urlset = 1;
  95. }
  96. } else {
  97. }
  98. break;
  99. /* arrowhead arrowsize arrowtail */
  100. case 'a':
  101. if (strcmp(l, "arrowhead") == 0) {
  102. /* todo fully parse the arrow combinations */
  103. arrownum = dp_getarrow(r);
  104. if (arrownum->pe) {
  105. if (arrownum->es) {
  106. res->ahnum = DP_EA_NORMAL;
  107. res->ahstring = dp_uniqstr((char *)"normal");
  108. } else {
  109. memset(dp_errmsg, 0, 256);
  110. snprintf(dp_errmsg, (256 - 1),
  111. "dot %s(): unknown edge arrowhead `%s' at line %d\n", __func__, r, res->yylineno);
  112. }
  113. } else {
  114. res->ahnum = arrownum->type;
  115. res->ahstring = arrownum->name;
  116. }
  117. res->bitflags0.ahset = 1;
  118. arrownum = (struct dparrow *)dp_free((void *)arrownum);
  119. if (arrownum) {
  120. }
  121. } else if (strcmp(l, "arrowsize") == 0) {
  122. num = dp_getnum(r);
  123. if (num->pe) {
  124. if (num->es) {
  125. res->asize = 1.0;
  126. res->bitflags0.asizeset = 1;
  127. } else {
  128. memset(dp_errmsg, 0, 256);
  129. snprintf(dp_errmsg, (256 - 1),
  130. "dot %s(): unknown number `%s' for arrowsize at line %d\n", __func__, r, res->yylineno);
  131. }
  132. } else {
  133. if (num->number < 0) {
  134. memset(dp_errmsg, 0, 256);
  135. snprintf(dp_errmsg, (256 - 1),
  136. "dot %s(): not allowed negative number `%s' for arrowsize at line %d\n", __func__, r, res->yylineno);
  137. } else {
  138. res->asize = num->number;
  139. res->bitflags0.asizeset = 1;
  140. }
  141. }
  142. num = (struct dpnum *)dp_free((void *)num);
  143. if (num) {
  144. }
  145. } else if (strcmp(l, "arrowtail") == 0) {
  146. /* todo fully parse the arrow combinations */
  147. arrownum = dp_getarrow(r);
  148. if (arrownum->pe) {
  149. if (arrownum->es) {
  150. res->atnum = DP_EA_NORMAL;
  151. res->atstring = dp_uniqstr((char *)"normal");
  152. } else {
  153. memset(dp_errmsg, 0, 256);
  154. snprintf(dp_errmsg, (256 - 1),
  155. "dot %s(): unknown edge arrowtail `%s' at line %d\n", __func__, r, res->yylineno);
  156. }
  157. } else {
  158. res->atnum = arrownum->type;
  159. res->atstring = arrownum->name;
  160. }
  161. res->bitflags0.atset = 1;
  162. arrownum = (struct dparrow *)dp_free((void *)arrownum);
  163. if (arrownum) {
  164. }
  165. } else {
  166. }
  167. break;
  168. /* color colorscheme comment constraint */
  169. case 'c':
  170. if (strcmp(l, "color") == 0) {
  171. colornum = dp_getcolor(res->bitflags0.csnumset, res->csnum, r);
  172. if (colornum->pe) {
  173. if (colornum->es) {
  174. /* default black color */
  175. res->ecolor = 0x00000000;
  176. res->bitflags0.ecolorset = 1;
  177. } else {
  178. memset(dp_errmsg, 0, 256);
  179. snprintf(dp_errmsg, (256 - 1), "dot %s(): unknown edge color `%s' at line %d\n", __func__, r, res->yylineno);
  180. }
  181. } else {
  182. /* todo */
  183. if (colornum->islist) {
  184. /* default black color */
  185. res->ecolor = 0x00000000;
  186. printf("dot %s(): color list at line %d not supported\n", __func__, res->yylineno);
  187. } else {
  188. res->ecolor = colornum->color;
  189. }
  190. res->bitflags0.ecolorset = 1;
  191. }
  192. colornum = (struct dpcolor *)dp_free((void *)colornum);
  193. if (colornum) {
  194. }
  195. } else if (strcmp(l, "colorscheme") == 0) {
  196. tmpi = dp_colorschemecode(r);
  197. if (tmpi == (-1)) {
  198. memset(dp_errmsg, 0, 256);
  199. snprintf(dp_errmsg, (256 - 1),
  200. "dot %s(): syntax error invalid name of colorscheme `%s' near line %d\n", __func__, r, yylineno);
  201. /* continue and error message will soon appear */
  202. } else {
  203. /* number oke for colorscheme */
  204. res->csnum = tmpi;
  205. res->bitflags0.csnumset = 1;
  206. }
  207. } else if (strcmp(l, "comment") == 0) {
  208. if (r) {
  209. if (strlen(r)) {
  210. res->comment = r;
  211. } else {
  212. res->comment = NULL;
  213. }
  214. res->bitflags0.comset = 1;
  215. }
  216. } else if (strcmp(l, "constraint") == 0) {
  217. boolnum = dp_getbool(r);
  218. if (boolnum->pe) {
  219. if (boolnum->es) {
  220. /* default */
  221. res->bitflags0.constraint = 0;
  222. res->bitflags0.constrset = 1;
  223. } else {
  224. memset(dp_errmsg, 0, 256);
  225. snprintf(dp_errmsg, (256 - 1),
  226. "dot %s(): not a boolean `%s' for constraint at line %d\n", __func__, r, res->yylineno);
  227. }
  228. } else {
  229. if (boolnum->number) {
  230. res->bitflags0.constraint = 1;
  231. } else {
  232. res->bitflags0.constraint = 0;
  233. }
  234. res->bitflags0.constrset = 1;
  235. }
  236. boolnum = (struct dpbool *)dp_free((void *)boolnum);
  237. if (boolnum) {
  238. }
  239. } else {
  240. }
  241. break;
  242. /* decorate dir */
  243. case 'd':
  244. if (strcmp(l, "decorate") == 0) {
  245. boolnum = dp_getbool(r);
  246. if (boolnum->pe) {
  247. if (boolnum->es) {
  248. /* default */
  249. res->bitflags0.decorate = 0;
  250. res->bitflags0.decorset = 1;
  251. } else {
  252. memset(dp_errmsg, 0, 256);
  253. snprintf(dp_errmsg, (256 - 1),
  254. "dot %s(): not a boolean `%s' for decorate at line %d\n", __func__, r, res->yylineno);
  255. }
  256. } else {
  257. if (boolnum->number) {
  258. res->bitflags0.decorate = 1;
  259. } else {
  260. res->bitflags0.decorate = 0;
  261. }
  262. res->bitflags0.decorset = 1;
  263. }
  264. boolnum = (struct dpbool *)dp_free((void *)boolnum);
  265. if (boolnum) {
  266. }
  267. } else if (strcmp(l, "dir") == 0) {
  268. dirnum = dp_getdir(r);
  269. if (dirnum->pe) {
  270. if (dirnum->es) {
  271. res->dir = DP_DIR_FORWARD;
  272. res->bitflags0.dirset = 1;
  273. } else {
  274. memset(dp_errmsg, 0, 256);
  275. snprintf(dp_errmsg, (256 - 1),
  276. "dot %s(): unknown dir type `%s' for dir at line %d\n", __func__, r, res->yylineno);
  277. }
  278. } else {
  279. res->dir = dirnum->type;
  280. res->bitflags0.dirset = 1;
  281. }
  282. dirnum = (struct dpdir *)dp_free((void *)dirnum);
  283. if (dirnum) {
  284. }
  285. } else {
  286. }
  287. break;
  288. /* edgeURL edgehref edgetarget edgetooltip */
  289. case 'e':
  290. if (strcmp(l, "edgeURL") == 0) {
  291. if (r) {
  292. if (strlen(r)) {
  293. res->url = r;
  294. } else {
  295. res->url = NULL;
  296. }
  297. res->bitflags0.urlset = 1;
  298. }
  299. } else if (strcmp(l, "edgehref") == 0) {
  300. if (r) {
  301. if (strlen(r)) {
  302. res->url = r;
  303. } else {
  304. res->url = NULL;
  305. }
  306. res->bitflags0.urlset = 1;
  307. }
  308. } else if (strcmp(l, "edgetarget") == 0) {
  309. /* svg map only */
  310. if (r) {
  311. if (strlen(r)) {
  312. res->etarg = r;
  313. } else {
  314. res->etarg = NULL;
  315. }
  316. res->bitflags0.etargset = 1;
  317. }
  318. } else if (strcmp(l, "edgetooltip") == 0) {
  319. if (r) {
  320. if (strlen(r)) {
  321. res->ett = r;
  322. } else {
  323. res->ett = NULL;
  324. }
  325. res->bitflags0.ettset = 1;
  326. }
  327. } else {
  328. }
  329. break;
  330. /* fontcolor fontname fontsize */
  331. case 'f':
  332. if (strcmp(l, "fontcolor") == 0) {
  333. colornum = dp_getcolor(res->bitflags0.csnumset, res->csnum, r);
  334. if (colornum->pe) {
  335. if (colornum->es) {
  336. /* default black color */
  337. res->fontcolor = 0x00000000;
  338. res->bitflags0.focolorset = 1;
  339. } else {
  340. memset(dp_errmsg, 0, 256);
  341. snprintf(dp_errmsg, (256 - 1),
  342. "dot %s(): unknown edge fontcolor `%s' at line %d\n", __func__, r, res->yylineno);
  343. }
  344. } else {
  345. /* todo */
  346. if (colornum->islist) {
  347. /* default black color */
  348. res->ecolor = 0x00000000;
  349. printf("dot %s(): color list at line %d not supported\n", __func__, res->yylineno);
  350. } else {
  351. res->fontcolor = colornum->color;
  352. }
  353. res->bitflags0.focolorset = 1;
  354. }
  355. colornum = (struct dpcolor *)dp_free((void *)colornum);
  356. if (colornum) {
  357. }
  358. } else if (strcmp(l, "fontname") == 0) {
  359. if (r) {
  360. if (strlen(r)) {
  361. res->fontname = r;
  362. } else {
  363. res->fontname = NULL;
  364. }
  365. res->bitflags0.fontnameset = 1;
  366. }
  367. } else if (strcmp(l, "fontsize") == 0) {
  368. /* size of font */
  369. num = dp_getnum(r);
  370. if (num->pe) {
  371. if (num->es) {
  372. /* number is "", use default. */
  373. res->fontsize = 14;
  374. res->bitflags0.fontsizeset = 1;
  375. } else {
  376. memset(dp_errmsg, 0, 256);
  377. snprintf(dp_errmsg, (256 - 1),
  378. "dot %s(): cannot parse fontsize number `%s' at line %d\n", __func__, r, res->yylineno);
  379. }
  380. } else {
  381. if (num->number >= 1.0) {
  382. /* round to int in double format */
  383. res->fontsize = rint(num->number);
  384. res->bitflags0.fontsizeset = 1;
  385. } else {
  386. memset(dp_errmsg, 0, 256);
  387. snprintf(dp_errmsg, (256 - 1),
  388. "dot %s(): fontsize number `%s' at line %d is too low\n", __func__, r, res->yylineno);
  389. }
  390. }
  391. num = (struct dpnum *)dp_free((void *)num);
  392. if (num) {
  393. }
  394. } else {
  395. }
  396. break;
  397. /* headURL head_lp headclip headhref headlabel headport headtarget headtooltip href */
  398. case 'h':
  399. if (strcmp(l, "headURL") == 0) {
  400. /* svg, map */
  401. if (r) {
  402. if (strlen(r)) {
  403. res->hurl = r;
  404. } else {
  405. res->hurl = NULL;
  406. }
  407. res->bitflags0.hurlset = 1;
  408. }
  409. } else if (strcmp(l, "head_lp") == 0) {
  410. /* point %f,%f for head label as string */
  411. /* parse (x,y) with optional '!' at end */
  412. if (r) {
  413. if (strlen(r)) {
  414. res->hlp = r;
  415. pointnum = dp_getpoint(r);
  416. if (pointnum->pe) {
  417. memset(dp_errmsg, 0, 256);
  418. snprintf(dp_errmsg, (256 - 1),
  419. "dot %s(): cannot parse head_lp (x,y) number `%s' at line %d\n", __func__, r, res->yylineno);
  420. } else {
  421. res->hlpx = pointnum->x;
  422. res->hlpy = pointnum->y;
  423. res->hlpflag = pointnum->flag;
  424. }
  425. pointnum = (struct dppoint *)dp_free((void *)pointnum);
  426. if (pointnum) {
  427. }
  428. } else {
  429. res->hlpx = 0;
  430. res->hlpy = 0;
  431. res->hlpflag = 0;
  432. res->hlp = NULL;
  433. }
  434. res->bitflags0.hlpset = 1;
  435. }
  436. } else if (strcmp(l, "headclip") == 0) {
  437. boolnum = dp_getbool(r);
  438. if (boolnum->pe) {
  439. if (boolnum->es) {
  440. /* default */
  441. res->bitflags0.headclip = 0;
  442. res->bitflags0.hcset = 1;
  443. } else {
  444. memset(dp_errmsg, 0, 256);
  445. snprintf(dp_errmsg, (256 - 1),
  446. "dot %s(): not a boolean `%s' for headclip at line %d\n", __func__, r, res->yylineno);
  447. }
  448. } else {
  449. if (boolnum->number) {
  450. res->bitflags0.headclip = 1;
  451. } else {
  452. res->bitflags0.headclip = 0;
  453. }
  454. res->bitflags0.hcset = 1;
  455. }
  456. boolnum = (struct dpbool *)dp_free((void *)boolnum);
  457. if (boolnum) {
  458. }
  459. } else if (strcmp(l, "headhref") == 0) {
  460. /* same as headURL */
  461. /* svg, map */
  462. if (r) {
  463. if (strlen(r)) {
  464. res->hurl = r;
  465. } else {
  466. res->hurl = NULL;
  467. }
  468. res->bitflags0.hurlset = 1;
  469. }
  470. } else if (strcmp(l, "headlabel") == 0) {
  471. if (r) {
  472. if (strlen(r)) {
  473. res->hlabel = r;
  474. } else {
  475. res->hlabel = NULL;
  476. }
  477. res->bitflags0.hlset = 1;
  478. }
  479. } else if (strcmp(l, "headport") == 0) {
  480. /* todo could be portname:compass ? */
  481. if (r) {
  482. if (strlen(r) == 0) {
  483. /* default is center 'c' */
  484. res->hport = (char *)"c";
  485. res->bitflags0.hportset = 1;
  486. } else {
  487. tmpi = dp_iscompass(r);
  488. if (tmpi == 0) {
  489. memset(dp_errmsg, 0, 256);
  490. snprintf(dp_errmsg, (256 - 1),
  491. "dot %s(): not a compass point `%s' for headport at line %d\n", __func__, r, res->yylineno);
  492. } else {
  493. res->hport = r;
  494. res->bitflags0.hportset = 1;
  495. }
  496. }
  497. }
  498. } else if (strcmp(l, "headtarget") == 0) {
  499. /* svg, map */
  500. if (r) {
  501. if (strlen(r)) {
  502. res->htarg = r;
  503. } else {
  504. res->htarg = NULL;
  505. }
  506. res->bitflags0.htargset = 1;
  507. }
  508. } else if (strcmp(l, "headtooltip") == 0) {
  509. /* svg, cmap */
  510. if (r) {
  511. if (strlen(r)) {
  512. res->htt = r;
  513. } else {
  514. res->htt = NULL;
  515. }
  516. res->bitflags0.httset = 1;
  517. }
  518. } else if (strcmp(l, "href") == 0) {
  519. if (r) {
  520. if (strlen(r)) {
  521. res->url = r;
  522. } else {
  523. res->url = NULL;
  524. }
  525. res->bitflags0.urlset = 1;
  526. }
  527. } else {
  528. }
  529. break;
  530. /* id */
  531. case 'i':
  532. if (strcmp(l, "id") == 0) {
  533. /* svg, map */
  534. if (r) {
  535. if (strlen(r)) {
  536. res->id = r;
  537. } else {
  538. res->id = NULL;
  539. }
  540. res->bitflags0.idset = 1;
  541. }
  542. } else {
  543. }
  544. break;
  545. /* label labelURL labelangle labeldistance labelfloat labelfontcolor labelfontname labelfontsize labelhref labeltarget labeltooltip layer len lhead lp ltail */
  546. case 'l':
  547. if (strcmp(l, "label") == 0) {
  548. if (r) {
  549. if (strlen(r)) {
  550. res->label = r;
  551. } else {
  552. /* using "" turns off the edge label */
  553. res->label = NULL;
  554. }
  555. res->bitflags0.labelset = 1;
  556. }
  557. } else if (strcmp(l, "labelURL") == 0) {
  558. /* url */
  559. if (r) {
  560. if (strlen(r)) {
  561. res->lurl = r;
  562. } else {
  563. /* using "" turns off the edge url */
  564. res->lurl = NULL;
  565. }
  566. res->bitflags0.lurlset = 1;
  567. }
  568. } else if (strcmp(l, "labelangle") == 0) {
  569. /* */
  570. num = dp_getnum(r);
  571. if (num->pe) {
  572. if (num->es) {
  573. /* number is "", use default. */
  574. res->la = -25;
  575. res->bitflags0.laset = 1;
  576. } else {
  577. memset(dp_errmsg, 0, 256);
  578. snprintf(dp_errmsg, (256 - 1),
  579. "dot %s(): cannot parse labelangle number `%s' at line %d\n", __func__, r, res->yylineno);
  580. }
  581. } else {
  582. if (num->number > -180.0 && num->number < 360) {
  583. /* round to int in double format */
  584. res->la = rint(num->number);
  585. res->bitflags0.laset = 1;
  586. } else {
  587. memset(dp_errmsg, 0, 256);
  588. snprintf(dp_errmsg, (256 - 1),
  589. "dot %s(): labelangle number `%s' at line %d is out-of-range -180...360\n",
  590. __func__, r, res->yylineno);
  591. }
  592. }
  593. num = (struct dpnum *)dp_free((void *)num);
  594. if (num) {
  595. }
  596. } else if (strcmp(l, "labeldistance") == 0) {
  597. /* */
  598. num = dp_getnum(r);
  599. if (num->pe) {
  600. if (num->es) {
  601. /* number is "", use default. */
  602. res->ldist = 1;
  603. res->bitflags0.ldistset = 1;
  604. } else {
  605. memset(dp_errmsg, 0, 256);
  606. snprintf(dp_errmsg, (256 - 1),
  607. "dot %s(): cannot parse labeldistance number `%s' at line %d\n", __func__, r, res->yylineno);
  608. }
  609. } else {
  610. if (num->number > 0) {
  611. /* */
  612. res->ldist = num->number;
  613. res->bitflags0.ldistset = 1;
  614. } else {
  615. memset(dp_errmsg, 0, 256);
  616. snprintf(dp_errmsg, (256 - 1),
  617. "dot %s(): labeldistance number `%s' at line %d is too low\n", __func__, r, res->yylineno);
  618. }
  619. }
  620. num = (struct dpnum *)dp_free((void *)num);
  621. if (num) {
  622. }
  623. } else if (strcmp(l, "labelfloat") == 0) {
  624. boolnum = dp_getbool(r);
  625. if (boolnum->pe) {
  626. if (boolnum->es) {
  627. /* default */
  628. res->bitflags1.lfloat = 0;
  629. res->bitflags1.lfloatset = 1;
  630. } else {
  631. memset(dp_errmsg, 0, 256);
  632. snprintf(dp_errmsg, (256 - 1),
  633. "dot %s(): not a boolean `%s' for labelfloat at line %d\n", __func__, r, res->yylineno);
  634. }
  635. } else {
  636. if (boolnum->number) {
  637. res->bitflags1.lfloat = 1;
  638. } else {
  639. res->bitflags1.lfloat = 0;
  640. }
  641. res->bitflags1.lfloatset = 1;
  642. }
  643. boolnum = (struct dpbool *)dp_free((void *)boolnum);
  644. if (boolnum) {
  645. }
  646. } else if (strcmp(l, "labelfontcolor") == 0) {
  647. colornum = dp_getcolor(res->bitflags0.csnumset, res->csnum, r);
  648. if (colornum->pe) {
  649. if (colornum->es) {
  650. /* default black color */
  651. res->lfontcolor = 0x00000000;
  652. res->bitflags1.lfocolorset = 1;
  653. } else {
  654. memset(dp_errmsg, 0, 256);
  655. snprintf(dp_errmsg, (256 - 1),
  656. "dot %s(): unknown labelfontcolor `%s' at line %d\n", __func__, r, res->yylineno);
  657. }
  658. } else {
  659. /* todo */
  660. if (colornum->islist) {
  661. /* default black color */
  662. res->ecolor = 0x00000000;
  663. printf("dot %s(): color list at line %d not supported\n", __func__, res->yylineno);
  664. } else {
  665. res->lfontcolor = colornum->color;
  666. }
  667. res->bitflags1.lfocolorset = 1;
  668. }
  669. colornum = (struct dpcolor *)dp_free((void *)colornum);
  670. if (colornum) {
  671. }
  672. } else if (strcmp(l, "labelfontname") == 0) {
  673. if (r) {
  674. if (strlen(r)) {
  675. res->lfontname = r;
  676. } else {
  677. res->lfontname = NULL;
  678. }
  679. res->bitflags1.lfontnameset = 1;
  680. }
  681. } else if (strcmp(l, "labelfontsize") == 0) {
  682. /* size of font */
  683. num = dp_getnum(r);
  684. if (num->pe) {
  685. if (num->es) {
  686. /* number is "", use default. */
  687. res->lfontsize = 14;
  688. res->bitflags1.lfontsizeset = 1;
  689. } else {
  690. memset(dp_errmsg, 0, 256);
  691. snprintf(dp_errmsg, (256 - 1),
  692. "dot %s(): cannot parse labelfontsize number `%s' at line %d\n", __func__, r, res->yylineno);
  693. }
  694. } else {
  695. if (num->number >= 1.0) {
  696. /* round to int in double format */
  697. res->lfontsize = rint(num->number);
  698. res->bitflags1.lfontsizeset = 1;
  699. } else {
  700. memset(dp_errmsg, 0, 256);
  701. snprintf(dp_errmsg, (256 - 1),
  702. "dot %s(): labelfontsize number `%s' at line %d is too low\n", __func__, r, res->yylineno);
  703. }
  704. }
  705. num = (struct dpnum *)dp_free((void *)num);
  706. if (num) {
  707. }
  708. } else if (strcmp(l, "labelhref") == 0) {
  709. /* url same as labelURL */
  710. if (r) {
  711. if (strlen(r)) {
  712. res->lurl = r;
  713. } else {
  714. /* using "" turns off the edge url */
  715. res->lurl = NULL;
  716. }
  717. res->bitflags0.lurlset = 1;
  718. }
  719. } else if (strcmp(l, "labeltarget") == 0) {
  720. if (r) {
  721. if (strlen(r)) {
  722. res->ltarg = r;
  723. } else {
  724. /* using "" turns off */
  725. res->ltarg = NULL;
  726. }
  727. res->bitflags1.ltargset = 1;
  728. }
  729. } else if (strcmp(l, "labeltooltip") == 0) {
  730. if (r) {
  731. if (strlen(r)) {
  732. res->ltt = r;
  733. } else {
  734. /* using "" turns off */
  735. res->ltt = NULL;
  736. }
  737. res->bitflags1.lttset = 1;
  738. }
  739. } else if (strcmp(l, "layer") == 0) {
  740. /* layer control string */
  741. if (r) {
  742. if (strlen(r)) {
  743. res->layer = r;
  744. } else {
  745. /* using "" turns off */
  746. res->layer = NULL;
  747. }
  748. res->bitflags1.layerset = 1;
  749. }
  750. } else if (strcmp(l, "len") == 0) {
  751. /* edge len in inches neato */
  752. num = dp_getnum(r);
  753. if (num->pe) {
  754. if (num->es) {
  755. /* number is "", use default. */
  756. res->len = 1;
  757. res->bitflags1.lenset = 1;
  758. } else {
  759. memset(dp_errmsg, 0, 256);
  760. snprintf(dp_errmsg, (256 - 1),
  761. "dot %s(): cannot parse len number `%s' at line %d\n", __func__, r, res->yylineno);
  762. }
  763. } else {
  764. if (num->number >= 0) {
  765. /* */
  766. res->len = num->number;
  767. res->bitflags1.lenset = 1;
  768. } else {
  769. memset(dp_errmsg, 0, 256);
  770. snprintf(dp_errmsg, (256 - 1),
  771. "dot %s(): len number `%s' at line %d is negative\n", __func__, r, res->yylineno);
  772. }
  773. }
  774. num = (struct dpnum *)dp_free((void *)num);
  775. if (num) {
  776. }
  777. } else if (strcmp(l, "lhead") == 0) {
  778. if (r) {
  779. if (strlen(r)) {
  780. res->lhead = r;
  781. } else {
  782. /* using "" turns off */
  783. res->lhead = NULL;
  784. }
  785. res->bitflags1.lheadset = 1;
  786. }
  787. } else if (strcmp(l, "lp") == 0) {
  788. if (r) {
  789. if (strlen(r)) {
  790. res->lp = r;
  791. pointnum = dp_getpoint(r);
  792. if (pointnum->pe) {
  793. memset(dp_errmsg, 0, 256);
  794. snprintf(dp_errmsg, (256 - 1),
  795. "dot %s(): cannot parse lp (x,y) number `%s' at line %d\n", __func__, r, res->yylineno);
  796. } else {
  797. res->lpx = pointnum->x;
  798. res->lpy = pointnum->y;
  799. res->lpflag = pointnum->flag;
  800. }
  801. pointnum = (struct dppoint *)dp_free((void *)pointnum);
  802. if (pointnum) {
  803. }
  804. } else {
  805. res->lp = NULL;
  806. }
  807. res->bitflags1.lpset = 1;
  808. }
  809. } else if (strcmp(l, "ltail") == 0) {
  810. if (r) {
  811. if (strlen(r)) {
  812. res->ltail = r;
  813. } else {
  814. /* using "" turns off */
  815. res->ltail = NULL;
  816. }
  817. res->bitflags1.ltailset = 1;
  818. }
  819. } else {
  820. }
  821. break;
  822. /* minlen */
  823. case 'm':
  824. if (strcmp(l, "minlen") == 0) {
  825. num = dp_getnum(r);
  826. if (num->pe) {
  827. if (num->es) {
  828. res->minlen = 0;
  829. res->bitflags1.minlenset = 1;
  830. } else {
  831. memset(dp_errmsg, 0, 256);
  832. snprintf(dp_errmsg, (256 - 1),
  833. "dot %s(): unknown number `%s' for penwidth at line %d\n", __func__, r, res->yylineno);
  834. }
  835. } else {
  836. if (num->number < 0) {
  837. memset(dp_errmsg, 0, 256);
  838. snprintf(dp_errmsg, (256 - 1),
  839. "dot %s(): not allowed negative number `%s' for minlen at line %d\n", __func__, r, res->yylineno);
  840. } else {
  841. res->minlen = rint(num->number);
  842. res->bitflags1.minlenset = 1;
  843. }
  844. }
  845. num = (struct dpnum *)dp_free((void *)num);
  846. if (num) {
  847. }
  848. } else {
  849. /* something else */
  850. }
  851. break;
  852. /* nojustify */
  853. case 'n':
  854. if (strcmp(l, "nojustify") == 0) {
  855. boolnum = dp_getbool(r);
  856. if (boolnum->pe) {
  857. if (boolnum->es) {
  858. /* default */
  859. res->bitflags1.nojust = 0;
  860. res->bitflags1.nojustset = 1;
  861. } else {
  862. memset(dp_errmsg, 0, 256);
  863. snprintf(dp_errmsg, (256 - 1),
  864. "dot %s(): not a boolean `%s' for nojustify at line %d\n", __func__, r, res->yylineno);
  865. }
  866. } else {
  867. if (boolnum->number) {
  868. res->bitflags1.nojust = 1;
  869. } else {
  870. res->bitflags1.nojust = 0;
  871. }
  872. res->bitflags1.nojustset = 1;
  873. }
  874. boolnum = (struct dpbool *)dp_free((void *)boolnum);
  875. if (boolnum) {
  876. }
  877. } else {
  878. }
  879. break;
  880. /* penwidth pos */
  881. case 'p':
  882. if (strcmp(l, "penwidth") == 0) {
  883. num = dp_getnum(r);
  884. if (num->pe) {
  885. if (num->es) {
  886. res->penwidth = 1;
  887. res->bitflags0.penwidthset = 1;
  888. } else {
  889. memset(dp_errmsg, 0, 256);
  890. snprintf(dp_errmsg, (256 - 1),
  891. "dot %s(): unknown number `%s' for penwidth at line %d\n", __func__, r, res->yylineno);
  892. }
  893. } else {
  894. if (num->number < 0) {
  895. memset(dp_errmsg, 0, 256);
  896. snprintf(dp_errmsg, (256 - 1),
  897. "dot %s(): not allowed negative number `%s' for penwidth at line %d\n", __func__, r, res->yylineno);
  898. } else {
  899. res->penwidth = num->number;
  900. res->bitflags0.penwidthset = 1;
  901. }
  902. }
  903. num = (struct dpnum *)dp_free((void *)num);
  904. if (num) {
  905. }
  906. } else if (strcmp(l, "pos") == 0) {
  907. /* example:[pos="e,1110,867.67 1110,904.33 1110,896.26 1110,886.65 1110,877.71"];
  908. * todo parse this pos string
  909. */
  910. if (r) {
  911. if (strlen(r)) {
  912. res->pos = r;
  913. } else {
  914. /* using "" turns off */
  915. res->pos = NULL;
  916. }
  917. res->bitflags1.posset = 1;
  918. }
  919. } else {
  920. }
  921. break;
  922. /* samehead sametail showboxes style */
  923. case 's':
  924. if (strcmp(l, "samehead") == 0) {
  925. if (r) {
  926. if (strlen(r)) {
  927. res->sameh = r;
  928. } else {
  929. /* using "" turns off */
  930. res->sameh = NULL;
  931. }
  932. res->bitflags1.samehset = 1;
  933. }
  934. } else if (strcmp(l, "sametail") == 0) {
  935. if (r) {
  936. if (strlen(r)) {
  937. res->samet = r;
  938. } else {
  939. /* using "" turns off */
  940. res->samet = NULL;
  941. }
  942. res->bitflags1.sametset = 1;
  943. }
  944. } else if (strcmp(l, "showboxes") == 0) {
  945. /* postscript, 0, 1, 2 */
  946. } else if (strcmp(l, "style") == 0) {
  947. stylenum = dp_getstyle(r);
  948. if (stylenum->pe) {
  949. if (stylenum->es) {
  950. /* at "" clear all */
  951. res->bitflags0.styleset = 0;
  952. res->bitflags1.dashed = 0;
  953. res->bitflags1.dashedset = 1;
  954. res->bitflags1.dotted = 0;
  955. res->bitflags1.dottedset = 1;
  956. res->bitflags1.solid = 0;
  957. res->bitflags1.solidset = 1;
  958. res->bitflags1.invis = 0;
  959. res->bitflags1.invisset = 1;
  960. res->bitflags1.bold = 0;
  961. res->bitflags1.boldset = 1;
  962. res->bitflags1.tapered = 0;
  963. res->bitflags1.taperedset = 1;
  964. res->penwidth = 1;
  965. res->bitflags0.penwidthset = 1;
  966. } else {
  967. if (stylenum->pe_unk) {
  968. /* parse error at unknown token */
  969. memset(dp_errmsg, 0, 256);
  970. snprintf(dp_errmsg, (256 - 1),
  971. "dot %s(): unknown token `%s' in `%s' for style at line %d\n",
  972. __func__, stylenum->unknown, r, res->yylineno);
  973. } else if (stylenum->pe_slw) {
  974. /* parse error at setlinewidth number */
  975. memset(dp_errmsg, 0, 256);
  976. snprintf(dp_errmsg, (256 - 1),
  977. "dot %s(): wrong number or negative number `%s' for setlinewidth in style at line %d\nuse penwidth instead of setlinewidth.\n",
  978. __func__, r, res->yylineno);
  979. } else if (stylenum->pe_exp) {
  980. /* missing number at setlinewidth */
  981. memset(dp_errmsg, 0, 256);
  982. snprintf(dp_errmsg, (256 - 1),
  983. "dot %s(): missing number `%s' for setlinewidth in style at line %d\nuse penwidth instead of setlinewidth.\n",
  984. __func__, r, res->yylineno);
  985. } else {
  986. /* other parse error */
  987. memset(dp_errmsg, 0, 256);
  988. snprintf(dp_errmsg, (256 - 1),
  989. "dot %s(): unknown error in `%s' for style at line %d\n", __func__, r, res->yylineno);
  990. }
  991. }
  992. } else {
  993. /* no parse errors if here, the E marked are for a edge: */
  994. /* int dashed; "dashed" parsed N+E */
  995. /* int dotted; "dotted" parsed N+E */
  996. /* int solid; "solid" parsed N+E */
  997. /* int invis; "invis" parsed N+E */
  998. /* int bold; "bold" parsed N+E */
  999. /* int tapered; "tapered" parsed E */
  1000. /* tolerated by dot is "filled" in E */
  1001. /* tolerated by dot is "rounded" in E */
  1002. if (stylenum->filled) {
  1003. if (0) { /* as error */
  1004. memset(dp_errmsg, 0, 256);
  1005. snprintf(dp_errmsg, (256 - 1),
  1006. "dot %s(): filled does not apply to edge in `%s' for style at line %d\n",
  1007. __func__, r, res->yylineno);
  1008. } else { /* as warning */
  1009. printf
  1010. ("dot %s(): filled does not apply to edge in `%s' for style at line %d\n", __func__, r, res->yylineno);
  1011. }
  1012. } else if (stylenum->striped) {
  1013. if (0) { /* as error */
  1014. memset(dp_errmsg, 0, 256);
  1015. snprintf(dp_errmsg, (256 - 1),
  1016. "dot %s(): striped does not apply to edge in `%s' for style at line %d\n",
  1017. __func__, r, res->yylineno);
  1018. } else { /* as warning */
  1019. printf("dot %s(): striped does not apply to edge in `%s' for style at line %d\n",
  1020. __func__, r, res->yylineno);
  1021. }
  1022. } else if (stylenum->wedged) {
  1023. if (0) { /* as error */
  1024. memset(dp_errmsg, 0, 256);
  1025. snprintf(dp_errmsg, (256 - 1),
  1026. "dot %s(): wedged does not apply to edge in `%s' for style at line %d\n",
  1027. __func__, r, res->yylineno);
  1028. } else { /* as warning */
  1029. printf("dot %s(): wedged does not apply to edge in `%s' for style at line %d\n",
  1030. __func__, r, res->yylineno);
  1031. }
  1032. } else if (stylenum->diagonals) {
  1033. if (0) { /* as error */
  1034. memset(dp_errmsg, 0, 256);
  1035. snprintf(dp_errmsg, (256 - 1),
  1036. "dot %s(): diagonals does not apply to edge in `%s' for style at line %d\n",
  1037. __func__, r, res->yylineno);
  1038. } else { /* as warning */
  1039. printf("dot %s(): diagonals does not apply to edge in `%s' for style at line %d\n",
  1040. __func__, r, res->yylineno);
  1041. }
  1042. } else if (stylenum->rounded) {
  1043. if (0) { /* as error */
  1044. memset(dp_errmsg, 0, 256);
  1045. snprintf(dp_errmsg, (256 - 1),
  1046. "dot %s(): rounded does not apply to edge in `%s' for style at line %d\n",
  1047. __func__, r, res->yylineno);
  1048. } else { /* as warning */
  1049. printf("dot %s(): rounded does not apply to edge in `%s' for style at line %d\n",
  1050. __func__, r, res->yylineno);
  1051. }
  1052. } else if (stylenum->radial) {
  1053. if (0) { /* as error */
  1054. memset(dp_errmsg, 0, 256);
  1055. snprintf(dp_errmsg, (256 - 1),
  1056. "dot %s(): radial does not apply to edge in `%s' for style at line %d\n",
  1057. __func__, r, res->yylineno);
  1058. } else { /* as warning */
  1059. printf("dot %s(): radial does not apply to edge in `%s' for style at line %d\n",
  1060. __func__, r, res->yylineno);
  1061. }
  1062. } else {
  1063. res->bitflags0.styleset = 1;
  1064. if (stylenum->slwset) {
  1065. res->penwidth = stylenum->slw;
  1066. res->bitflags0.penwidthset = 1;
  1067. }
  1068. if (stylenum->tapered) {
  1069. res->bitflags1.tapered = 1;
  1070. res->bitflags1.taperedset = 1;
  1071. }
  1072. if (stylenum->dashed) {
  1073. res->bitflags1.dashed = 1;
  1074. res->bitflags1.dashedset = 1;
  1075. }
  1076. if (stylenum->dotted) {
  1077. res->bitflags1.dotted = 1;
  1078. res->bitflags1.dottedset = 1;
  1079. }
  1080. if (stylenum->solid) {
  1081. res->bitflags1.solid = 1;
  1082. res->bitflags1.solidset = 1;
  1083. }
  1084. if (stylenum->invis) {
  1085. res->bitflags1.invis = 1;
  1086. res->bitflags1.invisset = 1;
  1087. }
  1088. if (stylenum->bold) {
  1089. res->bitflags1.bold = 1;
  1090. res->bitflags1.boldset = 1;
  1091. }
  1092. }
  1093. }
  1094. stylenum = (struct dpstyle *)dp_free((void *)stylenum);
  1095. if (stylenum) {
  1096. }
  1097. } else {
  1098. }
  1099. break;
  1100. /* tailURL tail_lp tailclip tailhref taillabel tailport tailtarget tailtooltip target tooltip */
  1101. case 't':
  1102. if (strcmp(l, "tailURL") == 0) {
  1103. /* same as headURL */
  1104. /* svg, map */
  1105. if (r) {
  1106. if (strlen(r)) {
  1107. res->turl = r;
  1108. } else {
  1109. res->turl = NULL;
  1110. }
  1111. res->bitflags1.turlset = 1;
  1112. }
  1113. } else if (strcmp(l, "tail_lp") == 0) {
  1114. /* point %f,%f for head label as string */
  1115. /* parse (x,y) with optional '!' at end */
  1116. if (r) {
  1117. if (strlen(r)) {
  1118. res->tlp = r;
  1119. pointnum = dp_getpoint(r);
  1120. if (pointnum->pe) {
  1121. memset(dp_errmsg, 0, 256);
  1122. snprintf(dp_errmsg, (256 - 1),
  1123. "dot %s(): cannot parse tail_lp (x,y) number `%s' at line %d\n", __func__, r, res->yylineno);
  1124. } else {
  1125. res->tlpx = pointnum->x;
  1126. res->tlpy = pointnum->y;
  1127. res->tlpflag = pointnum->flag;
  1128. }
  1129. pointnum = (struct dppoint *)dp_free((void *)pointnum);
  1130. if (pointnum) {
  1131. }
  1132. } else {
  1133. res->hlp = NULL;
  1134. }
  1135. res->bitflags1.tlpset = 1;
  1136. }
  1137. } else if (strcmp(l, "tailclip") == 0) {
  1138. boolnum = dp_getbool(r);
  1139. if (boolnum->pe) {
  1140. if (boolnum->es) {
  1141. /* default is 1 but "" set it to zero todo here 1 or 0 ? */
  1142. res->bitflags2.tailc = 0;
  1143. res->bitflags2.tailcset = 1;
  1144. } else {
  1145. memset(dp_errmsg, 0, 256);
  1146. snprintf(dp_errmsg, (256 - 1),
  1147. "dot %s(): not a boolean `%s' for tailclip at line %d\n", __func__, r, res->yylineno);
  1148. }
  1149. } else {
  1150. if (boolnum->number) {
  1151. res->bitflags2.tailc = 1;
  1152. } else {
  1153. res->bitflags2.tailc = 0;
  1154. }
  1155. res->bitflags2.tailcset = 1;
  1156. }
  1157. boolnum = (struct dpbool *)dp_free((void *)boolnum);
  1158. if (boolnum) {
  1159. }
  1160. } else if (strcmp(l, "tailhref") == 0) {
  1161. /* same as headURL */
  1162. /* svg, map */
  1163. if (r) {
  1164. if (strlen(r)) {
  1165. res->turl = r;
  1166. } else {
  1167. res->turl = NULL;
  1168. }
  1169. res->bitflags1.turlset = 1;
  1170. }
  1171. } else if (strcmp(l, "taillabel") == 0) {
  1172. if (r) {
  1173. if (strlen(r)) {
  1174. res->tlabel = r;
  1175. } else {
  1176. res->tlabel = NULL;
  1177. }
  1178. res->bitflags2.tlabelset = 1;
  1179. }
  1180. } else if (strcmp(l, "tailport") == 0) {
  1181. /* todo could be portname:compass ? */
  1182. if (r) {
  1183. if (strlen(r) == 0) {
  1184. /* default is center 'c' */
  1185. res->tlport = (char *)"c";
  1186. res->bitflags2.tportset = 1;
  1187. } else {
  1188. tmpi = dp_iscompass(r);
  1189. if (tmpi == 0) {
  1190. memset(dp_errmsg, 0, 256);
  1191. snprintf(dp_errmsg, (256 - 1),
  1192. "dot %s(): not a compass point `%s' for tailport at line %d\n", __func__, r, res->yylineno);
  1193. } else {
  1194. res->tlport = r;
  1195. res->bitflags2.tportset = 1;
  1196. }
  1197. }
  1198. }
  1199. } else if (strcmp(l, "tailtarget") == 0) {
  1200. if (r) {
  1201. if (strlen(r)) {
  1202. res->ttarg = r;
  1203. } else {
  1204. res->ttarg = NULL;
  1205. }
  1206. res->bitflags2.ttargset = 1;
  1207. }
  1208. } else if (strcmp(l, "tailtooltip") == 0) {
  1209. if (r) {
  1210. if (strlen(r)) {
  1211. res->ttt = r;
  1212. } else {
  1213. res->ttt = NULL;
  1214. }
  1215. res->bitflags2.tttset = 1;
  1216. }
  1217. } else if (strcmp(l, "target") == 0) {
  1218. if (r) {
  1219. if (strlen(r)) {
  1220. res->target = r;
  1221. } else {
  1222. res->target = NULL;
  1223. }
  1224. res->bitflags2.targetset = 1;
  1225. }
  1226. } else if (strcmp(l, "tooltip") == 0) {
  1227. if (r) {
  1228. if (strlen(r)) {
  1229. res->tt = r;
  1230. } else {
  1231. res->tt = NULL;
  1232. }
  1233. res->bitflags2.ttset = 1;
  1234. }
  1235. } else {
  1236. /* something else */
  1237. }
  1238. break;
  1239. /* weight */
  1240. case 'w':
  1241. if (strcmp(l, "weight") == 0) {
  1242. num = dp_getnum(r);
  1243. if (num->pe) {
  1244. if (num->es) {
  1245. res->weight = 1;
  1246. res->bitflags2.weightset = 1;
  1247. } else {
  1248. memset(dp_errmsg, 0, 256);
  1249. snprintf(dp_errmsg, (256 - 1),
  1250. "dot %s(): unknown number `%s' for weight at line %d\n", __func__, r, res->yylineno);
  1251. }
  1252. } else {
  1253. if (num->number < 0) {
  1254. memset(dp_errmsg, 0, 256);
  1255. snprintf(dp_errmsg, (256 - 1),
  1256. "dot %s(): not allowed negative number `%s' for weight at line %d\n", __func__, r, res->yylineno);
  1257. } else {
  1258. res->weight = num->number;
  1259. res->bitflags2.weightset = 1;
  1260. }
  1261. }
  1262. num = (struct dpnum *)dp_free((void *)num);
  1263. if (num) {
  1264. }
  1265. } else {
  1266. /* something else */
  1267. }
  1268. break;
  1269. /* xlabel xlp */
  1270. case 'x':
  1271. if (strcmp(l, "xlabel") == 0) {
  1272. if (r) {
  1273. if (strlen(r)) {
  1274. res->xlabel = r;
  1275. } else {
  1276. res->xlabel = NULL;
  1277. }
  1278. res->bitflags2.xlabelset = 1;
  1279. }
  1280. } else if (strcmp(l, "xlp") == 0) {
  1281. /* point %f,%f for head label as string */
  1282. /* parse (x,y) with optional '!' at end */
  1283. if (r) {
  1284. if (strlen(r)) {
  1285. res->xlp = r;
  1286. pointnum = dp_getpoint(r);
  1287. if (pointnum->pe) {
  1288. memset(dp_errmsg, 0, 256);
  1289. snprintf(dp_errmsg, (256 - 1),
  1290. "dot %s(): cannot parse xlp (x,y) number `%s' at line %d\n", __func__, r, res->yylineno);
  1291. } else {
  1292. res->xlpx = pointnum->x;
  1293. res->xlpy = pointnum->y;
  1294. res->xlpflag = pointnum->flag;
  1295. }
  1296. pointnum = (struct dppoint *)dp_free((void *)pointnum);
  1297. if (pointnum) {
  1298. }
  1299. } else {
  1300. res->xlp = NULL;
  1301. }
  1302. res->bitflags2.xlpset = 1;
  1303. }
  1304. } else {
  1305. /* something else */
  1306. }
  1307. break;
  1308. default:
  1309. /* something else */
  1310. break;
  1311. }
  1312. return;
  1313. }
  1314. /* set factory default */
  1315. void dp_edgefdef(struct dpedge *e)
  1316. {
  1317. /* url is (char *)0 */
  1318. /* arrowhead is normal as default */
  1319. e->ahnum = DP_EA_NORMAL;
  1320. e->ahstring = dp_uniqstr((char *)"normal");
  1321. e->bitflags0.ahset = 1;
  1322. /* arrowsize mult factor is 1 */
  1323. e->asize = 1.0;
  1324. e->bitflags0.asizeset = 1;
  1325. /* arrowtail is normal as default */
  1326. e->atnum = DP_EA_NORMAL;
  1327. e->atstring = dp_uniqstr((char *)"normal");
  1328. e->bitflags0.atset = 1;
  1329. /* colorscheme is 0 undefined */
  1330. /* comment is (char *)0 */
  1331. /* constraint is 0 false bool */
  1332. e->bitflags0.constraint = 1;
  1333. e->bitflags0.constrset = 1;
  1334. /* decorate is 0 bool false */
  1335. /* arrow direction */
  1336. e->dir = DP_DIR_FORWARD;
  1337. e->bitflags0.dirset = 1;
  1338. /* edgetarget is (char *)0 svg */
  1339. /* edgetooltip is (char *)0 */
  1340. /* fontcolor is 0 black */
  1341. /* fontname is (char *)0 */
  1342. /* fontsize is 14, min 1. */
  1343. e->fontsize = 14;
  1344. e->bitflags0.fontsizeset = 1;
  1345. /* headurl is (char *)0 */
  1346. /* headhref is same as headURL */
  1347. /* head_lp is (char *)0 */
  1348. /* headclip is 0 false */
  1349. /* headlabel is (char *)0 */
  1350. /* headport is default center, 'c' */
  1351. e->hport = (char *)"c";
  1352. e->bitflags0.hportset = 1;
  1353. /* headtarget is (char *)0 */
  1354. /* headtooltip is (char *)0 */
  1355. /* id is (char *)0 */
  1356. /* edge label is (char *)0 */
  1357. /* labelurl is (char *)0 */
  1358. /* labelangle */
  1359. e->la = -25;
  1360. e->bitflags0.laset = 1;
  1361. /* labeldistance */
  1362. e->ldist = 1;
  1363. e->bitflags0.ldistset = 1;
  1364. /* labelfloat is 0 false */
  1365. /* labelfontcolor is black 8 */
  1366. /* labelfontname is (char *)0 */
  1367. /* labelfontsize is 14, min 1. */
  1368. e->lfontsize = 14;
  1369. e->bitflags1.lfontsizeset = 1;
  1370. /* labeltarget is (char *)0 */
  1371. /* labeltooltip is (char *)0 */
  1372. /* layer is (char *)0 */
  1373. /* len neato */
  1374. e->len = 1;
  1375. e->bitflags1.lenset = 1;
  1376. /* lhead is (char *)0 */
  1377. /* ltail is (char *)0 */
  1378. /* lp is (char *)0 */
  1379. /* minlen is 0 */
  1380. /* nojustify is 0 false */
  1381. /* edge line thickness */
  1382. e->penwidth = 1;
  1383. e->bitflags0.penwidthset = 1;
  1384. /* pos is (char *)0 */
  1385. /* samehead is (char *)0 */
  1386. /* sametail is (char *)0 */
  1387. /* style bits are 0 off */
  1388. /* tailclip is true */
  1389. e->bitflags2.tailc = 1;
  1390. e->bitflags2.tailcset = 1;
  1391. /* tail label is (char *)0 */
  1392. /* tailport is default center, 'c' */
  1393. e->tlport = (char *)"c";
  1394. e->bitflags2.tportset = 1;
  1395. /* tailtarget is (char *)0 */
  1396. /* tailtooltip is (char *)0 */
  1397. /* target is (char *)0 */
  1398. /* tooltip is (char *)0 */
  1399. /* weight */
  1400. e->weight = 1;
  1401. e->bitflags2.weightset = 1;
  1402. /* xlabel is (char *)0 */
  1403. /* xlp is (char *)0 */
  1404. return;
  1405. }
  1406. /* set edge default */
  1407. void dp_edgegdef(struct dpedge *from, struct dpedge *e)
  1408. {
  1409. /* edge color */
  1410. if (from->bitflags0.ecolorset) {
  1411. e->ecolor = from->ecolor;
  1412. e->bitflags0.ecolorset = 1;
  1413. }
  1414. /* edge style */
  1415. if (from->bitflags0.styleset) {
  1416. e->style = from->style;
  1417. e->bitflags0.styleset = 1;
  1418. }
  1419. /* url */
  1420. if (from->bitflags0.urlset) {
  1421. e->url = from->url;
  1422. e->bitflags0.urlset = 1;
  1423. }
  1424. /* colorscheme */
  1425. if (from->bitflags0.csnumset) {
  1426. e->csnum = from->csnum;
  1427. e->bitflags0.csnumset = 1;
  1428. }
  1429. /* arrowhead */
  1430. if (from->bitflags0.ahset) {
  1431. e->ahnum = from->ahnum;
  1432. e->ahstring = from->ahstring;
  1433. e->bitflags0.ahset = 1;
  1434. }
  1435. /* arrowsize */
  1436. if (from->bitflags0.asizeset) {
  1437. e->asize = from->asize;
  1438. e->bitflags0.asizeset = 1;
  1439. }
  1440. /* arrowtail */
  1441. if (from->bitflags0.atset) {
  1442. e->atnum = from->atnum;
  1443. e->atstring = from->atstring;
  1444. e->bitflags0.atset = 1;
  1445. }
  1446. /* comment output data */
  1447. if (from->bitflags0.comset) {
  1448. e->comment = from->comment;
  1449. e->bitflags0.comset = 1;
  1450. }
  1451. /* constraint */
  1452. if (from->bitflags0.constrset) {
  1453. e->bitflags0.constraint = from->bitflags0.constraint;
  1454. e->bitflags0.constrset = 1;
  1455. }
  1456. /* decorate */
  1457. if (from->bitflags0.decorset) {
  1458. e->bitflags0.decorate = from->bitflags0.decorate;
  1459. e->bitflags0.decorset = 1;
  1460. }
  1461. /* arrow direction */
  1462. if (from->bitflags0.dirset) {
  1463. e->dir = from->dir;
  1464. e->bitflags0.dirset = 1;
  1465. }
  1466. /* edgetarget svg */
  1467. if (from->bitflags0.etargset) {
  1468. e->etarg = from->etarg;
  1469. e->bitflags0.etargset = 1;
  1470. }
  1471. /* edge tooltip for url */
  1472. if (from->bitflags0.ettset) {
  1473. e->ett = from->ett;
  1474. e->bitflags0.ettset = 1;
  1475. }
  1476. /* font color */
  1477. if (from->bitflags0.focolorset) {
  1478. e->fontcolor = from->fontcolor;
  1479. e->bitflags0.focolorset = 1;
  1480. }
  1481. /* fontname */
  1482. if (from->bitflags0.fontnameset) {
  1483. e->fontname = from->fontname;
  1484. e->bitflags0.fontnameset = 1;
  1485. }
  1486. /* fontsize is 14, min 1. */
  1487. if (from->bitflags0.fontsizeset) {
  1488. e->fontsize = from->fontsize;
  1489. e->bitflags0.fontsizeset = 1;
  1490. }
  1491. /* headurl svg.map */
  1492. if (from->bitflags0.hurlset) {
  1493. e->hurl = from->hurl;
  1494. e->bitflags0.hurlset = 1;
  1495. }
  1496. /* %f,%f head_lp point as string */
  1497. if (from->bitflags0.hlpset) {
  1498. e->hlpx = from->hlpx;
  1499. e->hlpy = from->hlpy;
  1500. e->hlpflag = from->hlpflag;
  1501. e->hlp = from->hlp;
  1502. e->bitflags0.hlpset = 1;
  1503. }
  1504. /* headclip bool */
  1505. if (from->bitflags0.hcset) {
  1506. e->bitflags0.headclip = from->bitflags0.headclip;
  1507. e->bitflags0.hcset = 1;
  1508. }
  1509. /* headlabel string */
  1510. if (from->bitflags0.hlset) {
  1511. e->hlabel = from->hlabel;
  1512. e->bitflags0.hlset = 1;
  1513. }
  1514. /* headport */
  1515. if (from->bitflags0.hportset) {
  1516. e->hport = from->hport;
  1517. e->bitflags0.hportset = 1;
  1518. }
  1519. /* headtarget svg map */
  1520. if (from->bitflags0.htargset) {
  1521. e->htarg = from->htarg;
  1522. e->bitflags0.htargset = 1;
  1523. }
  1524. /* headtooltip svg cmap */
  1525. if (from->bitflags0.httset) {
  1526. e->htt = from->htt;
  1527. e->bitflags0.httset = 1;
  1528. }
  1529. /* svg id */
  1530. if (from->bitflags0.idset) {
  1531. e->id = from->id;
  1532. e->bitflags0.idset = 1;
  1533. }
  1534. /* edge label */
  1535. if (from->bitflags0.labelset) {
  1536. e->label = from->label;
  1537. e->bitflags0.labelset = 1;
  1538. }
  1539. /* label url */
  1540. if (from->bitflags0.lurlset) {
  1541. e->lurl = from->lurl;
  1542. e->bitflags0.lurlset = 1;
  1543. }
  1544. /* labelangle */
  1545. if (from->bitflags0.laset) {
  1546. e->la = from->la;
  1547. e->bitflags0.laset = 1;
  1548. }
  1549. /* labeldistance */
  1550. if (from->bitflags0.ldistset) {
  1551. e->ldist = from->ldist;
  1552. e->bitflags0.ldistset = 1;
  1553. }
  1554. /* labelfloat */
  1555. if (from->bitflags1.lfloatset) {
  1556. e->bitflags1.lfloat = from->bitflags1.lfloat;
  1557. e->bitflags1.lfloatset = 1;
  1558. }
  1559. /* labelfont color */
  1560. if (from->bitflags1.lfocolorset) {
  1561. e->lfontcolor = from->lfontcolor;
  1562. e->bitflags1.lfocolorset = 1;
  1563. }
  1564. /* labelfontname */
  1565. if (from->bitflags1.lfontnameset) {
  1566. e->lfontname = from->lfontname;
  1567. e->bitflags1.lfontnameset = 1;
  1568. }
  1569. /* labelfontsize is 14, min 1. */
  1570. if (from->bitflags1.lfontsizeset) {
  1571. e->lfontsize = from->lfontsize;
  1572. e->bitflags1.lfontsizeset = 1;
  1573. }
  1574. /* labeltarget */
  1575. if (from->bitflags1.ltargset) {
  1576. e->ltarg = from->ltarg;
  1577. e->bitflags1.ltargset = 1;
  1578. }
  1579. /* labeltooltip svg cmap */
  1580. if (from->bitflags1.lttset) {
  1581. e->ltt = from->ltt;
  1582. e->bitflags1.lttset = 1;
  1583. }
  1584. /* layer control string */
  1585. if (from->bitflags1.layerset) {
  1586. e->layer = from->layer;
  1587. e->bitflags1.layerset = 1;
  1588. }
  1589. /* len neto */
  1590. if (from->bitflags1.lenset) {
  1591. e->len = from->len;
  1592. e->bitflags1.lenset = 1;
  1593. }
  1594. /* lhead */
  1595. if (from->bitflags1.lheadset) {
  1596. e->lhead = from->lhead;
  1597. e->bitflags1.lheadset = 1;
  1598. }
  1599. /* ltail */
  1600. if (from->bitflags1.ltailset) {
  1601. e->ltail = from->ltail;
  1602. e->bitflags1.ltailset = 1;
  1603. }
  1604. /* %f,%f lp point as string */
  1605. if (from->bitflags1.lpset) {
  1606. e->lpx = from->lpx;
  1607. e->lpy = from->lpy;
  1608. e->lpflag = from->lpflag;
  1609. e->lp = from->lp;
  1610. e->bitflags1.lpset = 1;
  1611. }
  1612. /* minlen */
  1613. if (from->bitflags1.minlenset) {
  1614. e->minlen = from->minlen;
  1615. e->bitflags1.minlenset = 1;
  1616. }
  1617. /* nojustify */
  1618. if (from->bitflags1.nojustset) {
  1619. e->bitflags1.nojust = from->bitflags1.nojust;
  1620. e->bitflags1.nojustset = 1;
  1621. }
  1622. /* edge line thickness */
  1623. if (from->bitflags0.penwidthset) {
  1624. e->penwidth = from->penwidth;
  1625. e->bitflags0.penwidthset = 1;
  1626. }
  1627. /* pos string */
  1628. if (from->bitflags1.posset) {
  1629. e->pos = from->pos;
  1630. e->bitflags1.posset = 1;
  1631. }
  1632. /* samehead */
  1633. if (from->bitflags1.samehset) {
  1634. e->sameh = from->sameh;
  1635. e->bitflags1.samehset = 1;
  1636. }
  1637. /* sametail */
  1638. if (from->bitflags1.sametset) {
  1639. e->samet = from->samet;
  1640. e->bitflags1.sametset = 1;
  1641. }
  1642. /* style bits */
  1643. if (from->bitflags0.styleset) {
  1644. e->bitflags0.styleset = 1;
  1645. }
  1646. if (from->bitflags1.taperedset) {
  1647. e->bitflags1.tapered = from->bitflags1.tapered;
  1648. e->bitflags1.taperedset = 1;
  1649. }
  1650. if (from->bitflags1.dashedset) {
  1651. e->bitflags1.dashed = from->bitflags1.dashed;
  1652. e->bitflags1.dashedset = 1;
  1653. }
  1654. if (from->bitflags1.dottedset) {
  1655. e->bitflags1.dotted = from->bitflags1.dotted;
  1656. e->bitflags1.dottedset = 1;
  1657. }
  1658. if (from->bitflags1.solidset) {
  1659. e->bitflags1.solid = from->bitflags1.solid;
  1660. e->bitflags1.solidset = 1;
  1661. }
  1662. if (from->bitflags1.invisset) {
  1663. e->bitflags1.invis = from->bitflags1.invis;
  1664. e->bitflags1.invisset = 1;
  1665. }
  1666. if (from->bitflags1.boldset) {
  1667. e->bitflags1.bold = from->bitflags1.bold;
  1668. e->bitflags1.boldset = 1;
  1669. }
  1670. /* tail url */
  1671. if (from->bitflags1.turlset) {
  1672. e->turl = from->turl;
  1673. e->bitflags1.turlset = 1;
  1674. }
  1675. /* %f,%f tail_lp point as string */
  1676. if (from->bitflags1.tlpset) {
  1677. e->tlpx = from->tlpx;
  1678. e->tlpy = from->tlpy;
  1679. e->tlpflag = from->tlpflag;
  1680. e->tlp = from->tlp;
  1681. e->bitflags1.tlpset = 1;
  1682. }
  1683. /* tailclip */
  1684. if (from->bitflags2.tailcset) {
  1685. e->bitflags2.tailc = from->bitflags2.tailc;
  1686. e->bitflags2.tailcset = 1;
  1687. }
  1688. /* taillabel */
  1689. if (from->bitflags2.tlabelset) {
  1690. e->tlabel = from->tlabel;
  1691. e->bitflags2.tlabelset = 1;
  1692. }
  1693. /* tailport */
  1694. if (from->bitflags2.tportset) {
  1695. e->tlport = from->tlport;
  1696. e->bitflags2.tportset = 1;
  1697. }
  1698. /* tailtarget svg map */
  1699. if (from->bitflags2.ttargset) {
  1700. e->ttarg = from->ttarg;
  1701. e->bitflags2.ttargset = 1;
  1702. }
  1703. /* tailtooltip svg cmap */
  1704. if (from->bitflags2.tttset) {
  1705. e->ttt = from->ttt;
  1706. e->bitflags2.tttset = 1;
  1707. }
  1708. /* target */
  1709. if (from->bitflags2.targetset) {
  1710. e->target = from->target;
  1711. e->bitflags2.targetset = 1;
  1712. }
  1713. /* tooltip */
  1714. if (from->bitflags2.ttset) {
  1715. e->tt = from->tt;
  1716. e->bitflags2.ttset = 1;
  1717. }
  1718. /* weight */
  1719. if (from->bitflags2.weightset) {
  1720. e->weight = from->weight;
  1721. e->bitflags2.weightset = 1;
  1722. }
  1723. /* xlabel */
  1724. if (from->bitflags2.xlabelset) {
  1725. e->xlabel = from->xlabel;
  1726. e->bitflags2.xlabelset = 1;
  1727. }
  1728. /* %f,%f xlp point as string */
  1729. if (from->bitflags2.xlpset) {
  1730. e->xlpx = from->xlpx;
  1731. e->xlpy = from->xlpy;
  1732. e->xlpflag = from->xlpflag;
  1733. e->xlp = from->xlp;
  1734. e->bitflags2.xlpset = 1;
  1735. }
  1736. return;
  1737. }
  1738. /* end */