code.cxx 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768
  1. //
  2. // "$Id: code.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
  3. //
  4. // Code output routines for the Fast Light Tool Kit (FLTK).
  5. //
  6. // Copyright 1998-2010 by Bill Spitzak and others.
  7. //
  8. // This library is free software. Distribution and use rights are outlined in
  9. // the file "COPYING" which should have been included with this file. If this
  10. // file is missing or damaged, see the license at:
  11. //
  12. // http://www.fltk.org/COPYING.php
  13. //
  14. // Please report all bugs and problems on the following page:
  15. //
  16. // http://www.fltk.org/str.php
  17. //
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include "../src/flstring.h"
  21. #include <stdarg.h>
  22. #include <FL/Fl.H>
  23. #include "Fl_Type.h"
  24. #include "alignment_panel.h"
  25. static FILE *code_file;
  26. static FILE *header_file;
  27. extern char i18n_program[];
  28. extern int i18n_type;
  29. extern const char* i18n_include;
  30. extern const char* i18n_function;
  31. extern const char* i18n_file;
  32. extern const char* i18n_set;
  33. // return true if c can be in a C identifier. I needed this so
  34. // it is not messed up by locale settings:
  35. int is_id(char c) {
  36. return (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') || c=='_';
  37. }
  38. ////////////////////////////////////////////////////////////////
  39. // Generate unique but human-readable identifiers:
  40. struct id {
  41. char* text;
  42. void* object;
  43. id *left, *right;
  44. id (const char* t, void* o) : text(strdup(t)), object(o) {left = right = 0;}
  45. ~id();
  46. };
  47. id::~id() {
  48. delete left;
  49. free((void *)text);
  50. delete right;
  51. }
  52. static id* id_root;
  53. const char* unique_id(void* o, const char* type, const char* name, const char* label) {
  54. char buffer[128];
  55. char* q = buffer;
  56. while (*type) *q++ = *type++;
  57. *q++ = '_';
  58. const char* n = name;
  59. if (!n || !*n) n = label;
  60. if (n && *n) {
  61. while (*n && !is_id(*n)) n++;
  62. while (is_id(*n)) *q++ = *n++;
  63. }
  64. *q = 0;
  65. // okay, search the tree and see if the name was already used:
  66. id** p = &id_root;
  67. int which = 0;
  68. while (*p) {
  69. int i = strcmp(buffer, (*p)->text);
  70. if (!i) {
  71. if ((*p)->object == o) return (*p)->text;
  72. // already used, we need to pick a new name:
  73. sprintf(q,"%x",++which);
  74. p = &id_root;
  75. continue;
  76. }
  77. else if (i < 0) p = &((*p)->left);
  78. else p = &((*p)->right);
  79. }
  80. *p = new id(buffer, o);
  81. return (*p)->text;
  82. }
  83. ////////////////////////////////////////////////////////////////
  84. // return current indentation:
  85. static const char* spaces = " ";
  86. int indentation;
  87. const char* indent() {
  88. int i = indentation; if (i>16) i = 16;
  89. return spaces+16-i;
  90. }
  91. ////////////////////////////////////////////////////////////////
  92. // declarations/include files:
  93. // Each string generated by write_declare is written only once to
  94. // the header file. This is done by keeping a binary tree of all
  95. // the calls so far and not printing it if it is in the tree.
  96. struct included {
  97. char *text;
  98. included *left, *right;
  99. included(const char *t) {
  100. text = strdup(t);
  101. left = right = 0;
  102. }
  103. ~included();
  104. };
  105. included::~included() {
  106. delete left;
  107. free((void *)text);
  108. delete right;
  109. }
  110. static included *included_root;
  111. int write_declare(const char *format, ...) {
  112. va_list args;
  113. char buf[1024];
  114. va_start(args, format);
  115. vsnprintf(buf, sizeof(buf), format, args);
  116. va_end(args);
  117. included **p = &included_root;
  118. while (*p) {
  119. int i = strcmp(buf,(*p)->text);
  120. if (!i) return 0;
  121. else if (i < 0) p = &((*p)->left);
  122. else p = &((*p)->right);
  123. }
  124. fprintf(header_file,"%s\n",buf);
  125. *p = new included(buf);
  126. return 1;
  127. }
  128. ////////////////////////////////////////////////////////////////
  129. // silly thing to prevent declaring unused variables:
  130. // When this symbol is on, all attempts to write code don't write
  131. // anything, but set a variable if it looks like the variable "o" is used:
  132. int varused_test;
  133. int varused;
  134. // write an array of C characters (adds a null):
  135. void write_cstring(const char *w, int length) {
  136. if (varused_test) {
  137. varused = 1;
  138. return;
  139. }
  140. const char *e = w+length;
  141. int linelength = 1;
  142. putc('\"', code_file);
  143. for (; w < e;) {
  144. int c = *w++;
  145. switch (c) {
  146. case '\b': c = 'b'; goto QUOTED;
  147. case '\t': c = 't'; goto QUOTED;
  148. case '\n': c = 'n'; goto QUOTED;
  149. case '\f': c = 'f'; goto QUOTED;
  150. case '\r': c = 'r'; goto QUOTED;
  151. case '\"':
  152. case '\'':
  153. case '\\':
  154. QUOTED:
  155. if (linelength >= 77) {fputs("\\\n",code_file); linelength = 0;}
  156. putc('\\', code_file);
  157. putc(c, code_file);
  158. linelength += 2;
  159. break;
  160. case '?': // prevent trigraphs by writing ?? as ?\?
  161. if (*(w-2) == '?') goto QUOTED;
  162. // else fall through:
  163. default:
  164. if (c >= ' ' && c < 127) {
  165. // a legal ASCII character
  166. if (linelength >= 78) {fputs("\\\n",code_file); linelength = 0;}
  167. putc(c, code_file);
  168. linelength++;
  169. break;
  170. }
  171. // otherwise we must print it as an octal constant:
  172. c &= 255;
  173. if (c < 8) {
  174. if (linelength >= 76) {fputs("\\\n",code_file); linelength = 0;}
  175. fprintf(code_file, "\\%o",c);
  176. linelength += 2;
  177. } else if (c < 64) {
  178. if (linelength >= 75) {fputs("\\\n",code_file); linelength = 0;}
  179. fprintf(code_file, "\\%o",c);
  180. linelength += 3;
  181. } else {
  182. if (linelength >= 74) {fputs("\\\n",code_file); linelength = 0;}
  183. fprintf(code_file, "\\%o",c);
  184. linelength += 4;
  185. }
  186. // We must not put more numbers after it, because some C compilers
  187. // consume them as part of the quoted sequence. Use string constant
  188. // pasting to avoid this:
  189. c = *w;
  190. if (w < e && ( (c>='0'&&c<='9') || (c>='a'&&c<='f') || (c>='A'&&c<='F') )) {
  191. putc('\"', code_file); linelength++;
  192. if (linelength >= 79) {fputs("\n",code_file); linelength = 0;}
  193. putc('\"', code_file); linelength++;
  194. }
  195. break;
  196. }
  197. }
  198. putc('\"', code_file);
  199. }
  200. // write a C string, quoting characters if necessary:
  201. void write_cstring(const char *w) {write_cstring(w,strlen(w));}
  202. // write an array of C binary data (does not add a null):
  203. void write_cdata(const char *s, int length) {
  204. if (varused_test) {
  205. varused = 1;
  206. return;
  207. }
  208. if (write_sourceview) {
  209. if (length>=0)
  210. fprintf(code_file, "{ /* ... %d bytes of binary data... */ }", length);
  211. else
  212. fprintf(code_file, "{ /* ... binary data... */ }");
  213. return;
  214. }
  215. if (length==-1) {
  216. fprintf(code_file, "{ /* ... undefined size binary data... */ }");
  217. return;
  218. }
  219. const unsigned char *w = (const unsigned char *)s;
  220. const unsigned char *e = w+length;
  221. int linelength = 1;
  222. putc('{', code_file);
  223. for (; w < e;) {
  224. unsigned char c = *w++;
  225. if (c>99) linelength += 4;
  226. else if (c>9) linelength += 3;
  227. else linelength += 2;
  228. if (linelength >= 77) {fputs("\n",code_file); linelength = 0;}
  229. fprintf(code_file, "%d", c);
  230. if (w<e) putc(',', code_file);
  231. }
  232. putc('}', code_file);
  233. }
  234. void write_c(const char* format,...) {
  235. if (varused_test) {
  236. varused = 1;
  237. return;
  238. }
  239. va_list args;
  240. va_start(args, format);
  241. vfprintf(code_file, format, args);
  242. va_end(args);
  243. }
  244. void write_h(const char* format,...) {
  245. if (varused_test) return;
  246. va_list args;
  247. va_start(args, format);
  248. vfprintf(header_file, format, args);
  249. va_end(args);
  250. }
  251. #include <FL/filename.H>
  252. int write_number;
  253. int write_sourceview;
  254. extern Fl_Widget_Class_Type *current_widget_class;
  255. // recursively dump code, putting children between the two parts
  256. // of the parent code:
  257. static Fl_Type* write_code(Fl_Type* p) {
  258. if (write_sourceview) {
  259. p->code_position = (int)ftell(code_file);
  260. if (p->header_position_end==-1)
  261. p->header_position = (int)ftell(header_file);
  262. }
  263. // write all code that come before the children code
  264. // (but don't write the last comment until the very end)
  265. if (!(p==Fl_Type::last && p->is_comment()))
  266. p->write_code1();
  267. // recursively write the code of all children
  268. Fl_Type* q;
  269. if (p->is_widget() && p->is_class()) {
  270. // Handle widget classes specially
  271. for (q = p->next; q && q->level > p->level;) {
  272. if (strcmp(q->type_name(), "Function")) q = write_code(q);
  273. else {
  274. int level = q->level;
  275. do {
  276. q = q->next;
  277. } while (q && q->level > level);
  278. }
  279. }
  280. // write all code that come after the children
  281. p->write_code2();
  282. for (q = p->next; q && q->level > p->level;) {
  283. if (!strcmp(q->type_name(), "Function")) q = write_code(q);
  284. else {
  285. int level = q->level;
  286. do {
  287. q = q->next;
  288. } while (q && q->level > level);
  289. }
  290. }
  291. write_h("};\n");
  292. current_widget_class = 0L;
  293. } else {
  294. for (q = p->next; q && q->level > p->level;) q = write_code(q);
  295. // write all code that come after the children
  296. p->write_code2();
  297. }
  298. if (write_sourceview) {
  299. p->code_position_end = (int)ftell(code_file);
  300. if (p->header_position_end==-1)
  301. p->header_position_end = (int)ftell(header_file);
  302. }
  303. return q;
  304. }
  305. extern const char* header_file_name;
  306. extern Fl_Class_Type *current_class;
  307. extern const char *code_file_name;
  308. int write_code_block(Fl_Block_Type *block) {
  309. const char *filemode = "w";
  310. if (write_sourceview)
  311. filemode = "wb";
  312. write_number++;
  313. int x, y;
  314. Fl_Type* first_type;
  315. Fl_Type* last_type;
  316. const char *hdr;
  317. const char *file_name_base = block->get_file_name();
  318. char buf[1024];
  319. *buf = '\0';
  320. //return value
  321. int ret_value = 0;
  322. //save globals
  323. id *saved_id_root = id_root;
  324. int saved_indentation = indentation;
  325. Fl_Class_Type *saved_current_class = current_class;
  326. Fl_Widget_Class_Type *saved_current_widget_class = current_widget_class;
  327. FILE *saved_code_file = code_file;
  328. FILE *saved_header_file = header_file;
  329. included *saved_included_root = included_root;
  330. included_root = 0;
  331. id_root = 0;
  332. indentation = 0;
  333. current_class = 0L;
  334. current_widget_class = 0L;
  335. if (!file_name_base) code_file = stdout;
  336. else {
  337. snprintf(buf, sizeof(buf),"%s.%s", file_name_base,
  338. code_file_name ? code_file_name : "cpp");
  339. FILE *f = fopen(buf, filemode);
  340. if (!f){
  341. ret_value = 0;
  342. goto restore_on_return;
  343. }
  344. code_file = f;
  345. }
  346. if (!file_name_base) header_file = stdout;
  347. else {
  348. snprintf(buf, sizeof(buf),"%s.%s", file_name_base,
  349. header_file_name ? header_file_name : "h");
  350. FILE *f = fopen(buf, filemode);
  351. if (!f) {
  352. fclose(code_file);
  353. ret_value = 0;
  354. goto restore_on_return;
  355. }
  356. header_file = f;
  357. }
  358. // if the first entry in the Type tree is a comment, then it is probably
  359. // a copyright notice. We print that before anything else in the file!
  360. first_type = Fl_Type::last;
  361. if (first_type && first_type->is_comment()) {
  362. if (write_sourceview) {
  363. first_type->code_position = (int)ftell(code_file);
  364. first_type->header_position = (int)ftell(header_file);
  365. }
  366. // it is ok to write non-recusive code here, because comments have no children or code2 blocks
  367. first_type->write_code1();
  368. if (write_sourceview) {
  369. first_type->code_position_end = (int)ftell(code_file);
  370. first_type->header_position_end = (int)ftell(header_file);
  371. }
  372. }
  373. first_type = block;
  374. hdr = "\
  375. // generated by Fast Light User Interface Designer (fluid) version %.4f\n\n";
  376. fprintf(header_file, hdr, FL_VERSION);
  377. fprintf(code_file, hdr, FL_VERSION);
  378. {char define_name[102];
  379. const char* a = fl_filename_name(buf);
  380. char* b = define_name;
  381. if (!isalpha(*a)) {*b++ = '_';}
  382. while (*a) {*b++ = isalnum(*a) ? *a : '_'; a++;}
  383. *b = 0;
  384. fprintf(header_file, "#ifndef %s\n", define_name);
  385. fprintf(header_file, "#define %s\n", define_name);
  386. }
  387. write_declare("#include <FL/Fl.H>");
  388. if (i18n_type && i18n_include[0]) {
  389. if (i18n_include[0] != '<' &&
  390. i18n_include[0] != '\"')
  391. write_c("#include \"%s\"\n", i18n_include);
  392. else
  393. write_c("#include %s\n", i18n_include);
  394. if (i18n_type == 2) {
  395. if (i18n_file[0]) write_c("extern nl_catd %s;\n", i18n_file);
  396. else {
  397. write_c("// Initialize I18N stuff now for menus...\n");
  398. write_c("#include <locale.h>\n");
  399. write_c("static char *_locale = setlocale(LC_MESSAGES, \"\");\n");
  400. write_c("static nl_catd _catalog = catopen(\"%s\", 0);\n",
  401. i18n_program);
  402. }
  403. }
  404. }
  405. if (*buf && include_H_from_C) {
  406. if (*header_file_name == '.' && strchr(header_file_name, '/') == NULL) {
  407. write_c("#include \"%s\"\n", fl_filename_name(buf));
  408. } else {
  409. write_c("#include \"%s\"\n", buf);
  410. }
  411. }
  412. for (Fl_Type* p = first_type; p;) {
  413. // write all static data for this & all children first
  414. if (write_sourceview) p->header_position = (int)ftell(header_file);
  415. p->write_static();
  416. if (write_sourceview) {
  417. p->header_position_end = (int)ftell(header_file);
  418. if (p->header_position==p->header_position_end) p->header_position_end = -1;
  419. }
  420. for (Fl_Type* q = p->next; q && q->level > p->level; q = q->next) {
  421. if (write_sourceview) q->header_position = (int)ftell(header_file);
  422. q->write_static();
  423. if (write_sourceview) {
  424. q->header_position_end = (int)ftell(header_file);
  425. if (q->header_position==q->header_position_end) q->header_position_end = -1;
  426. }
  427. }
  428. // then write the nested code:
  429. p = write_code(p);
  430. }
  431. delete included_root; included_root = 0;
  432. if (!*buf) {
  433. ret_value = 1;
  434. goto restore_on_return;
  435. }
  436. fprintf(header_file, "#endif\n");
  437. last_type = Fl_Type::last;
  438. if (last_type && last_type->is_comment()) {
  439. if (write_sourceview) {
  440. last_type->code_position = (int)ftell(code_file);
  441. last_type->header_position = (int)ftell(header_file);
  442. }
  443. last_type->write_code1();
  444. if (write_sourceview) {
  445. last_type->code_position_end = (int)ftell(code_file);
  446. last_type->header_position_end = (int)ftell(header_file);
  447. }
  448. }
  449. x = fclose(code_file);
  450. code_file = 0;
  451. y = fclose(header_file);
  452. header_file = 0;
  453. ret_value = x >= 0 && y >= 0;
  454. restore_on_return:
  455. //restore globals
  456. id_root = saved_id_root;
  457. indentation = saved_indentation;
  458. current_class = saved_current_class;
  459. current_widget_class = saved_current_widget_class;
  460. code_file = saved_code_file;
  461. header_file = saved_header_file;
  462. included_root = saved_included_root;
  463. return ret_value;
  464. }
  465. int write_code(const char *s, const char *t) {
  466. const char *filemode = "w";
  467. if (write_sourceview)
  468. filemode = "wb";
  469. write_number++;
  470. delete id_root; id_root = 0;
  471. indentation = 0;
  472. current_class = 0L;
  473. current_widget_class = 0L;
  474. if (!s) code_file = stdout;
  475. else {
  476. FILE *f = fl_fopen(s, filemode);
  477. if (!f) return 0;
  478. code_file = f;
  479. }
  480. if (!t) header_file = stdout;
  481. else {
  482. FILE *f = fl_fopen(t, filemode);
  483. if (!f) {fclose(code_file); return 0;}
  484. header_file = f;
  485. }
  486. // if the first entry in the Type tree is a comment, then it is probably
  487. // a copyright notice. We print that before anything else in the file!
  488. Fl_Type* first_type = Fl_Type::first;
  489. if (first_type && first_type->is_comment()) {
  490. if (write_sourceview) {
  491. first_type->code_position = (int)ftell(code_file);
  492. first_type->header_position = (int)ftell(header_file);
  493. }
  494. // it is ok to write non-recusive code here, because comments have no children or code2 blocks
  495. first_type->write_code1();
  496. if (write_sourceview) {
  497. first_type->code_position_end = (int)ftell(code_file);
  498. first_type->header_position_end = (int)ftell(header_file);
  499. }
  500. first_type = first_type->next;
  501. }
  502. const char *hdr = "\
  503. // generated by Fast Light User Interface Designer (fluid) version %.4f\n\n";
  504. fprintf(header_file, hdr, FL_VERSION);
  505. fprintf(code_file, hdr, FL_VERSION);
  506. {char define_name[102];
  507. const char* a = fl_filename_name(t);
  508. char* b = define_name;
  509. if (!isalpha(*a)) {*b++ = '_';}
  510. while (*a) {*b++ = isalnum(*a) ? *a : '_'; a++;}
  511. *b = 0;
  512. fprintf(header_file, "#ifndef %s\n", define_name);
  513. fprintf(header_file, "#define %s\n", define_name);
  514. }
  515. write_declare("#include <FL/Fl.H>");
  516. if (i18n_type && i18n_include[0]) {
  517. if (i18n_include[0] != '<' &&
  518. i18n_include[0] != '\"')
  519. write_c("#include \"%s\"\n", i18n_include);
  520. else
  521. write_c("#include %s\n", i18n_include);
  522. if (i18n_type == 2) {
  523. if (i18n_file[0]) write_c("extern nl_catd %s;\n", i18n_file);
  524. else {
  525. write_c("// Initialize I18N stuff now for menus...\n");
  526. write_c("#include <locale.h>\n");
  527. write_c("static char *_locale = setlocale(LC_MESSAGES, \"\");\n");
  528. write_c("static nl_catd _catalog = catopen(\"%s\", 0);\n",
  529. i18n_program);
  530. }
  531. }
  532. }
  533. if (t && include_H_from_C) {
  534. if (*header_file_name == '.' && strchr(header_file_name, '/') == NULL) {
  535. write_c("#include \"%s\"\n", fl_filename_name(t));
  536. } else {
  537. write_c("#include \"%s\"\n", t);
  538. }
  539. }
  540. for (Fl_Type* p = first_type; p;) {
  541. // write all static data for this & all children first
  542. if (write_sourceview) p->header_position = (int)ftell(header_file);
  543. p->write_static();
  544. if (write_sourceview) {
  545. p->header_position_end = (int)ftell(header_file);
  546. if (p->header_position==p->header_position_end) p->header_position_end = -1;
  547. }
  548. for (Fl_Type* q = p->next; q && q->level > p->level; q = q->next) {
  549. if (write_sourceview) q->header_position = (int)ftell(header_file);
  550. q->write_static();
  551. if (write_sourceview) {
  552. q->header_position_end = (int)ftell(header_file);
  553. if (q->header_position==q->header_position_end) q->header_position_end = -1;
  554. }
  555. }
  556. // then write the nested code:
  557. p = write_code(p);
  558. }
  559. delete included_root; included_root = 0;
  560. if (!s) return 1;
  561. fprintf(header_file, "#endif\n");
  562. Fl_Type* last_type = Fl_Type::last;
  563. if (last_type && last_type->is_comment()) {
  564. if (write_sourceview) {
  565. last_type->code_position = (int)ftell(code_file);
  566. last_type->header_position = (int)ftell(header_file);
  567. }
  568. last_type->write_code1();
  569. if (write_sourceview) {
  570. last_type->code_position_end = (int)ftell(code_file);
  571. last_type->header_position_end = (int)ftell(header_file);
  572. }
  573. }
  574. int x = fclose(code_file);
  575. code_file = 0;
  576. int y = fclose(header_file);
  577. header_file = 0;
  578. return x >= 0 && y >= 0;
  579. }
  580. int write_strings(const char *sfile) {
  581. FILE *fp = fl_fopen(sfile, "w");
  582. Fl_Type *p;
  583. Fl_Widget_Type *w;
  584. int i;
  585. if (!fp) return 1;
  586. switch (i18n_type) {
  587. case 0 : /* None, just put static text out */
  588. fprintf(fp, "# generated by Fast Light User Interface Designer (fluid) version %.4f\n",
  589. FL_VERSION);
  590. for (p = Fl_Type::first; p; p = p->next) {
  591. if (p->is_widget()) {
  592. w = (Fl_Widget_Type *)p;
  593. if (w->label()) {
  594. for (const char *s = w->label(); *s; s ++)
  595. if (*s < 32 || *s > 126 || *s == '\"')
  596. fprintf(fp, "\\%03o", *s);
  597. else
  598. putc(*s, fp);
  599. putc('\n', fp);
  600. }
  601. if (w->tooltip()) {
  602. for (const char *s = w->tooltip(); *s; s ++)
  603. if (*s < 32 || *s > 126 || *s == '\"')
  604. fprintf(fp, "\\%03o", *s);
  605. else
  606. putc(*s, fp);
  607. putc('\n', fp);
  608. }
  609. }
  610. }
  611. break;
  612. case 1 : /* GNU gettext, put a .po file out */
  613. fprintf(fp, "# generated by Fast Light User Interface Designer (fluid) version %.4f\n",
  614. FL_VERSION);
  615. for (p = Fl_Type::first; p; p = p->next) {
  616. if (p->is_widget()) {
  617. w = (Fl_Widget_Type *)p;
  618. if (w->label()) {
  619. const char *s;
  620. fputs("msgid \"", fp);
  621. for (s = w->label(); *s; s ++)
  622. if (*s < 32 || *s > 126 || *s == '\"')
  623. fprintf(fp, "\\%03o", *s);
  624. else
  625. putc(*s, fp);
  626. fputs("\"\n", fp);
  627. fputs("msgstr \"", fp);
  628. for (s = w->label(); *s; s ++)
  629. if (*s < 32 || *s > 126 || *s == '\"')
  630. fprintf(fp, "\\%03o", *s);
  631. else
  632. putc(*s, fp);
  633. fputs("\"\n", fp);
  634. }
  635. if (w->tooltip()) {
  636. const char *s;
  637. fputs("msgid \"", fp);
  638. for (s = w->tooltip(); *s; s ++)
  639. if (*s < 32 || *s > 126 || *s == '\"')
  640. fprintf(fp, "\\%03o", *s);
  641. else
  642. putc(*s, fp);
  643. fputs("\"\n", fp);
  644. fputs("msgstr \"", fp);
  645. for (s = w->tooltip(); *s; s ++)
  646. if (*s < 32 || *s > 126 || *s == '\"')
  647. fprintf(fp, "\\%03o", *s);
  648. else
  649. putc(*s, fp);
  650. fputs("\"\n", fp);
  651. }
  652. }
  653. }
  654. break;
  655. case 2 : /* POSIX catgets, put a .msg file out */
  656. fprintf(fp, "$ generated by Fast Light User Interface Designer (fluid) version %.4f\n",
  657. FL_VERSION);
  658. fprintf(fp, "$set %s\n", i18n_set);
  659. fputs("$quote \"\n", fp);
  660. for (i = 1, p = Fl_Type::first; p; p = p->next) {
  661. if (p->is_widget()) {
  662. w = (Fl_Widget_Type *)p;
  663. if (w->label()) {
  664. fprintf(fp, "%d \"", i ++);
  665. for (const char *s = w->label(); *s; s ++)
  666. if (*s < 32 || *s > 126 || *s == '\"')
  667. fprintf(fp, "\\%03o", *s);
  668. else
  669. putc(*s, fp);
  670. fputs("\"\n", fp);
  671. }
  672. if (w->tooltip()) {
  673. fprintf(fp, "%d \"", i ++);
  674. for (const char *s = w->tooltip(); *s; s ++)
  675. if (*s < 32 || *s > 126 || *s == '\"')
  676. fprintf(fp, "\\%03o", *s);
  677. else
  678. putc(*s, fp);
  679. fputs("\"\n", fp);
  680. }
  681. }
  682. }
  683. break;
  684. }
  685. return fclose(fp);
  686. }
  687. ////////////////////////////////////////////////////////////////
  688. void Fl_Type::write_static() {}
  689. void Fl_Type::write_code1() {
  690. write_h("// Header for %s\n", title());
  691. write_c("// Code for %s\n", title());
  692. }
  693. void Fl_Type::write_code2() {}
  694. //
  695. // End of "$Id: code.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
  696. //