📄 file.cxx
字号:
//// "$Id: file.cxx,v 1.1.1.1 2003/08/07 21:18:39 jasonk Exp $"//// Fluid file routines for the Fast Light Tool Kit (FLTK).//// You may find the basic read_* and write_* routines to// be useful for other programs. I have used them many times.// They are somewhat similar to tcl, using matching { and }// to quote strings.//// Copyright 1998-1999 by Bill Spitzak and others.//// This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Library General Public// License as published by the Free Software Foundation; either// version 2 of the License, or (at your option) any later version.//// This library 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// Library General Public License for more details.//// You should have received a copy of the GNU Library General Public// License along with this library; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307// USA.//// Please report all bugs and problems to "fltk-bugs@easysw.com".//#include <ctype.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdarg.h>#include "alignment_panel.h"////////////////////////////////////////////////////////////////// BASIC FILE WRITING:static FILE *fout;int open_write(const char *s) { if (!s) {fout = stdout; return 1;} FILE *f = fopen(s,"w"); if (!f) return 0; fout = f; return 1;}int close_write() { if (fout != stdout) { int x = fclose(fout); fout = stdout; return x >= 0; } return 1;}static int needspace;int is_id(char); // in code.C// write a string, quoting characters if necessary:void write_word(const char *w) { if (needspace) putc(' ', fout); needspace = 1; if (!w || !*w) {fprintf(fout,"{}"); return;} const char *p; // see if it is a single word: for (p = w; is_id(*p); p++) ; if (!*p) {fprintf(fout,"%s",w); return;} // see if there are matching braces: int n = 0; for (p = w; *p; p++) { if (*p == '{') n++; else if (*p == '}') {n--; if (n<0) break;} } int mismatched = (n != 0); // write out brace-quoted string: putc('{', fout); for (; *w; w++) { switch (*w) { case '{': case '}': if (!mismatched) break; case '\\': case '#': putc('\\',fout); break; } putc(*w,fout); } putc('}', fout);}// write an arbitrary formatted word, or a comment, etc:void write_string(const char *format, ...) { va_list args; va_start(args, format); if (needspace) fputc(' ',fout); vfprintf(fout, format, args); va_end(args); needspace = !isspace(format[strlen(format)-1]);}// start a new line and indent it for a given nesting level:void write_indent(int n) { fputc('\n',fout); while (n--) {fputc(' ',fout); fputc(' ',fout);} needspace = 0;}// write a '{' at the given indenting level:void write_open(int) { if (needspace) fputc(' ',fout); fputc('{',fout); needspace = 0;}// write a '}' at the given indenting level:void write_close(int n) { if (needspace) write_indent(n); fputc('}',fout); needspace = 1;}////////////////////////////////////////////////////////////////// BASIC FILE READING:static FILE *fin;static int lineno;static const char *fname;int open_read(const char *s) { lineno = 1; if (!s) {fin = stdin; fname = "stdin"; return 1;} FILE *f = fopen(s,"r"); if (!f) return 0; fin = f; fname = s; return 1;}int close_read() { if (fin != stdin) { int x = fclose(fin); fin = 0; return x >= 0; } return 1;}#include <FL/fl_message.H>void read_error(const char *format, ...) { va_list args; va_start(args, format); if (!fin) { char buffer[1024]; vsprintf(buffer, format, args); fl_message(buffer); } else { fprintf(stderr, "%s:%d: ", fname, lineno); vfprintf(stderr, format, args); fprintf(stderr, "\n"); } va_end(args);}static int hexdigit(int x) { if (isdigit(x)) return x-'0'; if (isupper(x)) return x-'A'+10; if (islower(x)) return x-'a'+10; return 20;}static int read_quoted() { // read whatever character is after a \ . int c,d,x; switch(c = fgetc(fin)) { case '\n': lineno++; return -1; case 'a' : return('\a'); case 'b' : return('\b'); case 'f' : return('\f'); case 'n' : return('\n'); case 'r' : return('\r'); case 't' : return('\t'); case 'v' : return('\v'); case 'x' : /* read hex */ for (c=x=0; x<3; x++) { int ch = fgetc(fin); d = hexdigit(ch); if (d > 15) {ungetc(ch,fin); break;} c = (c<<4)+d; } break; default: /* read octal */ if (c<'0' || c>'7') break; c -= '0'; for (x=0; x<2; x++) { int ch = fgetc(fin); d = hexdigit(ch); if (d>7) {ungetc(ch,fin); break;} c = (c<<3)+d; } break; } return(c);}// return a word read from the file, or NULL at the EOF:// This will skip all comments (# to end of line), and evaluate// all \xxx sequences and use \ at the end of line to remove the newline.// A word is any one of:// a continuous string of non-space chars except { and } and #// everything between matching {...} (unless wantbrace != 0)// the characters '{' and '}'static char *buffer;static int buflen;static void expand_buffer(int length) { if (length >= buflen) { if (!buflen) { buflen = length+1; buffer = (char*)malloc(buflen); } else { buflen = 2*buflen; if (length >= buflen) buflen = length+1; buffer = (char *)realloc((void *)buffer,buflen); } }}const char *read_word(int wantbrace) { int x; // skip all the whitespace before it: for (;;) { x = getc(fin); if (x < 0) { // eof return 0; } else if (x == '#') { // comment do x = getc(fin); while (x >= 0 && x != '\n'); lineno++; continue; } else if (x == '\n') { lineno++; } else if (!isspace(x)) { break; } } expand_buffer(100); if (x == '{' && !wantbrace) { // read in whatever is between braces int length = 0; int nesting = 0; for (;;) { x = getc(fin); if (x<0) {read_error("Missing '}'"); break;} else if (x == '#') { // embedded comment do x = getc(fin); while (x >= 0 && x != '\n'); lineno++; continue; } else if (x == '\n') lineno++; else if (x == '\\') {x = read_quoted(); if (x<0) continue;} else if (x == '{') nesting++; else if (x == '}') {if (!nesting--) break;} buffer[length++] = x; expand_buffer(length); } buffer[length] = 0; return buffer; } else if (x == '{' || x == '}') { // all the punctuation is a word: buffer[0] = x; buffer[1] = 0; return buffer; } else { // read in an unquoted word: int length = 0; for (;;) { if (x == '\\') {x = read_quoted(); if (x<0) continue;} else if (x<0 || isspace(x) || x=='{' || x=='}' || x=='#') break; buffer[length++] = x; expand_buffer(length); x = getc(fin); } ungetc(x, fin); buffer[length] = 0; return buffer; }}////////////////////////////////////////////////////////////////#include <FL/Fl.H>#include "Fl_Widget_Type.h"// global int variables:extern int gridx, gridy, snap;static struct {const char* name; int* value;} inttable[] = { {"gridx", &gridx}, {"gridy", &gridy}, {"snap", &snap}};extern int header_file_set;extern int code_file_set;extern const char* header_file_name;extern const char* code_file_name;int write_file(const char *filename, int selected_only) { if (!open_write(filename)) return 0; write_string("# data file for the Fltk User Interface Designer (fluid)\n" "version %.2f",FL_VERSION); if(!include_H_from_C) write_string("\ndo_not_include_H_from_C"); if (!selected_only) { write_string("\nheader_name"); write_word(header_file_name); write_string("\ncode_name"); write_word(code_file_name); for (unsigned int i=0; i<sizeof(inttable)/sizeof(*inttable); i++) write_string("\n%s %d",inttable[i].name, *inttable[i].value); } for (Fl_Type *p = Fl_Type::first; p;) { if (!selected_only || p->selected) { p->write(); write_string("\n"); int q = p->level; for (p = p->next; p && p->level > q; p = p->next); } else { p = p->next; } } return close_write();}////////////////////////////////////////////////////////////////// read all the objects out of the input file:void read_fdesign();double read_version;extern Fl_Type *Fl_Type_make(const char *tn);static void read_children(Fl_Type *p, int paste) { Fl_Type::current = p; for (;;) { unsigned int i; const char *c = read_word(); REUSE_C: if (!c) { if (p && !paste) read_error("Missing '}'"); break; } if (!strcmp(c,"}")) { if (!p) read_error("Unexpected '}'"); break; } // this is the first word in a .fd file: if (!strcmp(c,"Magic:")) { read_fdesign(); return; } if (!strcmp(c,"version")) { c = read_word(); read_version = strtod(c,0); if (read_version<=0 || read_version>FL_VERSION) read_error("unknown version '%s'",c); continue; } // back compatability with Vincent Penne's original class code: if (!p && !strcmp(c,"define_in_struct")) { Fl_Type *t = Fl_Type_make("class"); t->name(read_word()); Fl_Type::current = p = t; paste = 1; // stops "missing }" error continue; } if (!strcmp(c,"do_not_include_H_from_C")) { include_H_from_C=0; goto CONTINUE; } if (!strcmp(c,"header_name")) { if (!header_file_set) header_file_name = strdup(read_word()); else read_word(); goto CONTINUE; } if (!strcmp(c,"code_name")) { if (!code_file_set) code_file_name = strdup(read_word()); else read_word(); goto CONTINUE; } for (i=0; i<sizeof(inttable)/sizeof(*inttable); i++) { if (!strcmp(c,inttable[i].name)) { c = read_word(); *inttable[i].value = atoi(c); goto CONTINUE; } } {Fl_Type *t = Fl_Type_make(c); if (!t) { read_error("Unknown word \"%s\"", c); continue; } t->name(read_word()); c = read_word(1); if (strcmp(c,"{")) { read_error("Missing property list for %s\n",t->title()); goto REUSE_C; } t->open_ = 0; for (;;) { const char *c = read_word(); if (!c || !strcmp(c,"}")) break; t->read_property(c); } if (!t->is_parent()) continue; c = read_word(1); if (strcmp(c,"{")) { read_error("Missing child list for %s\n",t->title()); goto REUSE_C; } read_children(t, 0);} Fl_Type::current = p; CONTINUE:; }}extern void deselect();int read_file(const char *filename, int merge) { read_version = 0.0; if (!open_read(filename)) return 0; if (merge) deselect(); else delete_all(); read_children(Fl_Type::current, merge); Fl_Type::current = 0; for (Fl_Type *o = Fl_Type::first; o; o = o->next) if (o->selected) {Fl_Type::current = o; break;} return close_read();}////////////////////////////////////////////////////////////////// Read Forms and XForms fdesign files:int read_fdesign_line(const char*& name, const char*& value) { int length = 0; int x; // find a colon: for (;;) { x = getc(fin); if (x < 0) return 0; if (x == '\n') {length = 0; continue;} // no colon this line... if (!isspace(x)) { buffer[length++] = x; expand_buffer(length); } if (x == ':') break; } int valueoffset = length; buffer[length-1] = 0; // skip to start of value: for (;;) { x = getc(fin); if (x < 0 || x == '\n' || !isspace(x)) break; } // read the value: for (;;) { if (x == '\\') {x = read_quoted(); if (x<0) continue;} else if (x == '\n') break; buffer[length++] = x; expand_buffer(length); x = getc(fin); } buffer[length] = 0; name = buffer; value = buffer+valueoffset; return 1;}int fdesign_flip;int fdesign_magic;#include <FL/Fl_Group.H>static const char *class_matcher[] = {"FL_CHECKBUTTON", "Fl_Check_Button","FL_ROUNDBUTTON", "Fl_Round_Button","FL_ROUND3DBUTTON", "Fl_Round_Button","FL_LIGHTBUTTON", "Fl_Light_Button","FL_FRAME", "Fl_Box","FL_LABELFRAME", "Fl_Box","FL_TEXT", "Fl_Box","FL_VALSLIDER", "Fl_Value_Slider","FL_MENU", "Fl_Menu_Button","3", "FL_BITMAP","1", "FL_BOX","71","FL_BROWSER","11","FL_BUTTON","4", "FL_CHART","42","FL_CHOICE","61","FL_CLOCK","25","FL_COUNTER","22","FL_DIAL","101","FL_FREE","31","FL_INPUT","12","Fl_Light_Button","41","FL_MENU","23","FL_POSITIONER","13","Fl_Round_Button","21","FL_SLIDER","2", "FL_BOX", // was FL_TEXT"62","FL_TIMER","24","Fl_Value_Slider",0};void read_fdesign() { fdesign_magic = atoi(read_word()); fdesign_flip = (fdesign_magic < 13000); Fl_Widget_Type *window = 0; Fl_Widget_Type *group = 0; Fl_Widget_Type *widget = 0; if (!Fl_Type::current) { Fl_Type *t = Fl_Type_make("Function"); t->name("create_the_forms()"); Fl_Type::current = t; } for (;;) { const char *name; const char *value; if (!read_fdesign_line(name, value)) break; if (!strcmp(name,"Name")) { window = (Fl_Widget_Type*)Fl_Type_make("Fl_Window"); window->name(value); window->label(value); Fl_Type::current = widget = window; } else if (!strcmp(name,"class")) { if (!strcmp(value,"FL_BEGIN_GROUP")) { group = widget = (Fl_Widget_Type*)Fl_Type_make("Fl_Group"); Fl_Type::current = group; } else if (!strcmp(value,"FL_END_GROUP")) { if (group) { Fl_Group* g = (Fl_Group*)(group->o); g->begin(); g->forms_end(); Fl_Group::current(0); } group = widget = 0; Fl_Type::current = window; } else { for (int i = 0; class_matcher[i]; i += 2) if (!strcmp(value,class_matcher[i])) { value = class_matcher[i+1]; break;} widget = (Fl_Widget_Type*)Fl_Type_make(value); if (!widget) { printf("class %s not found, using Fl_Button\n", value); widget = (Fl_Widget_Type*)Fl_Type_make("Fl_Button"); } } } else if (widget) { if (!widget->read_fdesign(name, value)) printf("Ignoring \"%s: %s\"\n", name, value); } }}//// End of "$Id: file.cxx,v 1.1.1.1 2003/08/07 21:18:39 jasonk Exp $".//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -