📄 options.c
字号:
/*options.cParses command line options and provides options control panel with aninteractive Web interface for the Web server (webserver.c).--------------------------------------------------------------------------------gSOAP XML Web services toolsCopyright (C) 2001-2004, Robert van Engelen, Genivia, Inc. All Rights Reserved.This software is released under one of the following two licenses:GPL or Genivia's license for commercial use.--------------------------------------------------------------------------------GPL license.This program is free software; you can redistribute it and/or modify it underthe terms of the GNU General Public License as published by the Free SoftwareFoundation; either version 2 of the License, or (at your option) any laterversion.This program is distributed in the hope that it will be useful, but WITHOUT ANYWARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR APARTICULAR PURPOSE. See the GNU General Public License for more details.You should have received a copy of the GNU General Public License along withthis program; if not, write to the Free Software Foundation, Inc., 59 TemplePlace, Suite 330, Boston, MA 02111-1307 USAAuthor contact information:engelen@genivia.com / engelen@acm.org--------------------------------------------------------------------------------A commercial use license is available from Genivia, Inc., contact@genivia.com--------------------------------------------------------------------------------*/#define SOAP_NOGLOBAL#define SOAP_FMAC3 static#include "optC.c"#include "options.h"#include "httpget.h"#ifdef WIN32#define OPTION_CHAR '/'#else#define OPTION_CHAR '-'#endifstruct option *copy_options(const struct option *options);int parse_options(int argc, char **argv, struct option *options);void query_options(struct soap *soap, struct option *options);int load_options(const char *file, const char *name, struct option *options);int save_options(const char *file, const char *name, struct option *options);int html_options(struct soap *soap, struct option *options);int html_form_options(struct soap *soap, struct option *options);static int set_option(const char *key, const char *val, struct option *options);static int set_selection(const char *val, struct option *p);static int find_selection(const char *value, const char *selections);static void print_usage(int argc, char **argv, struct option *options);struct option *copy_options(const struct option *options){ struct option *p; int n; for (n = 0; options[n].name; n++) ; p = (struct option*)malloc((n + 1) * sizeof(struct option)); if (p) { for (n = 0; options[n].name; n++) { p[n].name = options[n].name; p[n].selections = options[n].selections; p[n].selected = options[n].selected; if (options[n].value) { p[n].value = (char*)malloc(strlen(options[n].value) + 1); strcpy(p[n].value, options[n].value); } else p[n].value = NULL; } p[n].name = NULL; p[n].selections = NULL; p[n].selected = 0; p[n].value = NULL; } return p;}void free_options(struct option *options){ if (options) { struct option *p; for (p = options; p->name; p++ ) { if (p->value) free(p->value); } free(options); }}int parse_options(int argc, char **argv, struct option *options){ int i; for (i = 1; i < argc; i++) { const char *key, *val; key = argv[i]; if (*key == OPTION_CHAR) { int flag = 1; while (flag && *++key) { if (*key == '?' || !strcmp(key, "help")) { print_usage(argc, argv, options); return 1; } if (i < argc) val = argv[i + 1]; else val = NULL; switch (set_option(key, val, options)) { case 2: i++; case 1: flag = 0; case 0: break; case -1: fprintf(stderr, "%s: missing argument value for option %c%s\n", argv[0], OPTION_CHAR, key); print_usage(argc, argv, options); return 1; case -2: fprintf(stderr, "%s: unknown option %c%s\n", argv[0], OPTION_CHAR, key); print_usage(argc, argv, options); return 1; } } } else if (set_option(NULL, key, options) < 0) fprintf(stderr, "%s: invalid argument %s\n", argv[0], key); } return 0;}void query_options(struct soap *soap, struct option *options){ char *s = query(soap); /* get arguments from query string */ while (s) { char *key = query_key(soap, &s); /* decode next query string key */ char *val = query_val(soap, &s); /* decode next query string value */ if (key) set_option(key, val, options); }}int load_options(const char *file, const char *name, struct option *options){ struct soap soap; soap_init(&soap); if (file) { soap.recvfd = open(file, O_RDONLY); if (soap.recvfd < 0) { soap_done(&soap); return EOF; } } if (!soap_begin_recv(&soap) && !soap_element_begin_in(&soap, name, 1, NULL)) { struct t__Option t; while (soap_in_t__Option(&soap, "option", &t, NULL)) if (set_option(t.key, t.val, options) < 0) ; /* error, just ignore for now */ if (!soap_element_end_in(&soap, name)) soap_end_recv(&soap); } if (file) close(soap.recvfd); soap_end(&soap); soap_done(&soap); return soap.error;}int save_options(const char *file, const char *name, struct option *options){ struct soap soap; soap_init1(&soap, SOAP_XML_TREE); soap.namespaces = NULL; soap.encodingStyle = NULL; if (file) { soap.sendfd = open(file, O_CREAT | O_RDWR, 0644); if (soap.sendfd < 0) { soap_done(&soap); return EOF; } } if (!soap_begin_send(&soap) && !soap_element_begin_out(&soap, name, 0, NULL)) { struct option *p; struct t__Option t; for (p = options; p->name; p++) { t.val = NULL; if (!p->name[0]) { if (!p->value) continue; t.key = NULL; t.val = p->value; } else if (p->name[1] == '.') t.key = (char*)p->name + 2; else t.key = (char*)p->name; if (p->selections && strchr(p->selections, ' ')) { const char *s = p->selections - 1; char *r; int i; for (i = p->selected; i > 0; i--) { s = strchr(s + 1, ' '); if (!s) break; } if (s) { t.val = soap_strdup(&soap, s + 1); r = strchr(t.val, ' '); if (r) *r = '\0'; } } else if (p->value) t.val = p->value; else if (!p->selected) continue; if (soap_out_t__Option(&soap, "option", 0, &t, NULL)) break; } if (!soap_element_end_out(&soap, name)) soap_end_send(&soap); } if (file) close(soap.sendfd); soap_end(&soap); soap_done(&soap); return soap.error;}int html_options(struct soap *soap, struct option *options){ struct option *p; soap_send(soap, "<table border='0' cellspacing='0' cellpadding='0' bgcolor='#666666' nosave>\n"); soap_send(soap, "<tr height='10'><td background='btl.gif'></td><td background='bt.gif'></td><td background='bt.gif'></td><td background='bt.gif'></td><td background='bt.gif'></td><td background='bt.gif'></td><td width='10' background='btr.gif'></td><td width='10' height='10' background='obls.gif'></td></tr>"); for (p = options; p->name; p++) { const char *s, *t, *n; int i; n = p->name; if (n[0] && n[1] == '.') n += 2; s = p->selections; soap_send(soap, "<tr><td background='bl.gif'></td><td align='right'>"); if (!n[0]) { if (s) soap_send(soap, s); soap_send(soap, "</td><td></td><td></td><td></td><td>"); if (p->value) soap_send(soap, p->value); soap_send(soap, "</td>"); } else if (!s) { soap_send(soap, n); soap_send(soap, "</td><td width='10' background='ls.gif'></td><td bgcolor='#FFFFFF'><a href='?"); soap_send(soap, n); if (p->selected) soap_send(soap, "='><img src='checked.gif' align='absmiddle' border='0'></a></td><td width='10' background='rs.gif'></td><td>on</td>"); else soap_send(soap, "'><img src='unchecked.gif' align='absmiddle' border='0'></a></td><td width='10' background='rs.gif'></td><td>off</td>"); } else if (strchr(s, ' ')) { soap_send(soap, n); soap_send(soap, "</td>"); for (i = 0; ; i++) { t = strchr(s, ' '); if (i == 0) soap_send(soap, "<td width='10' background='ls.gif'></td><td bgcolor='#FFFFFF'>"); else soap_send(soap, "<tr><td background='bl.gif'></td><td></td><td width='10' background='ls.gif'></td><td bgcolor='#FFFFFF'>"); if (i == p->selected) soap_send(soap, "<img src='selected.gif' align='absmiddle' border='0'></td><td width='10' background='rs.gif'></td><td>"); else { soap_send(soap, "<a href='?"); soap_send(soap, n); soap_send(soap, "="); if (t) soap_send_raw(soap, s, t - s); else soap_send(soap, s); soap_send(soap, "'>"); soap_send(soap, "<img src='deselected.gif' align='absmiddle' border='0'></a></td><td width='10' background='rs.gif'></td><td>"); } if (t) soap_send_raw(soap, s, t - s); else soap_send(soap, s); soap_send(soap, "</td>"); if (!t) break; soap_send(soap, "<td width='10' background='br.gif'></td><td width='10' background='ls.gif'></td></tr>\n"); s = t + 1; } } else { char buf[16]; soap_send(soap, n); soap_send(soap, "</td><td width='10' background='ls.gif'></td><td bgcolor='#FFFFFF'> </td><td width='10' background='rs.gif'></td><td><input type='text' name='"); soap_send(soap, n); soap_send(soap, "' value='"); if (p->value) soap_send(soap, p->value); soap_send(soap, "' size='"); sprintf(buf, "%d", p->selected > 0 ? p->selected : 24); soap_send(soap, buf); soap_send(soap, "'><input type='submit' value='Set "); soap_send(soap, s); soap_send(soap, "'></td>"); } soap_send(soap, "<td width='10' background='br.gif'></td><td width='10' background='ls.gif'></td></tr>\n"); // <tr height='1'><td height='1' background='bl.gif'></td><td></td><td></td><td></td><td></td><td width='10' height='1' background='br.gif'></td><td width='10' height='1' background='ls.gif'></td></tr>\n"); } soap_send(soap, "<tr height='10'><td background='bbl.gif'></td><td background='bb.gif'></td><td background='bb.gif'></td><td background='bb.gif'></td><td background='bb.gif'></td><td background='bb.gif'></td><td width='10' background='bbr.gif'><td width='10' height='10' background='ls.gif'</td></tr>\n<tr height='10'><td width='10' height='10' background=otrs.gif></td><td height='10' background='ts.gif'></td><td height='10' background='ts.gif'></td><td height='10' background='ts.gif'></td><td height='10' background='ts.gif'></td><td height='10' background='ts.gif'></td><td height='10' background='ts.gif'></td><td width='10' height='10' background='otls.gif'></td></tr>\n</table>\n"); return SOAP_OK;}int html_form_options(struct soap *soap, struct option *options){ soap_send(soap, "<form action='' method='get' name='form'>"); html_options(soap, options); return soap_send(soap, "</form>");}static int set_option(const char *key, const char *val, struct option *options){ struct option *p; if (!key) { for (p = options; p->name; p++) { if (!p->name[0]) { if (p->value) { char *s = (char*)malloc(strlen(p->value) + strlen(val) + 1); if (s) { strcpy(s, p->value); strcat(s, " "); strcat(s, val); free((void*)p->value); p->value = s; } } else { p->value = (char*)malloc(strlen(val) + 1); if (p->value) strcpy(p->value, val); } return 2; } } return -2; } for (p = options; p->name; p++) { if (p->name[0] && ((p->name[1] == '.' && !strcmp(key, p->name + 2)) || (p->name[1] != '.' && !strcmp(key, p->name)))) { if (p->selections) { if (!val) return -1; if (set_selection(val, p) < 0) return -1; return 2; } if (val && !*val) { p->selected = 0; return 2; } p->selected = 1; return 1; } } for (p = options; p->name; p++) { if (p->name[0] == key[0] && p->name[1] == '.') { if (p->selections) { const char *s = key + 1; if (!s[0]) { s = val; if (!s) return -1; } if (set_selection(s, p) < 0) return -1; if (s == val) return 2; return 1; } p->selected = 1; return 0; } } return -2;}static int set_selection(const char *val, struct option *p){ if (strchr(p->selections, ' ')) return p->selected = find_selection(val, p->selections); if (p->value) free(p->value); p->value = (char*)malloc(strlen(val) + 1); if (p->value) strcpy(p->value, val); return 0;}static int find_selection(const char *val, const char *selections){ int i = 0; const char *s = selections; size_t n = strlen(val); for (;;) { if (!strncmp(s, val, n) && (s[n] == ' ' || s[n] == '\0')) return i; s = strchr(s, ' '); if (!s) break; s++; i++; } return -1;}static void print_usage(int argc, char **argv, struct option *options){ struct option *p; fprintf(stderr, "Usage: %s", argv[0]); for (p = options; p->name; p++) { if (p->name[0]) { int flag = (p->name[1] == '.'); if (p->selections) { if (strchr(p->selections, ' ')) { if (flag) fprintf(stderr, " %c%c[%s]", OPTION_CHAR, p->name[0], p->selections); else fprintf(stderr, " %c%s [%s]", OPTION_CHAR, p->name, p->selections); } else if (flag) fprintf(stderr, " %c%c<%s>", OPTION_CHAR, p->name[0], p->selections); else fprintf(stderr, " %c%s <%s>", OPTION_CHAR, p->name, p->selections); } else if (flag) fprintf(stderr, " %c%c", OPTION_CHAR, p->name[0]); else fprintf(stderr, " %c%s", OPTION_CHAR, p->name); } else if (p->selections) fprintf(stderr, " %s", p->selections); else fprintf(stderr, " ..."); } fprintf(stderr, "\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -