示例#1
0
/*********************************************************************************
 * The contents of this file are subject to the Common Public Attribution
 * License Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.openemm.org/cpal1.html. The License is based on the Mozilla
 * Public License Version 1.1 but Sections 14 and 15 have been added to cover
 * use of software over a computer network and provide for limited attribution
 * for the Original Developer. In addition, Exhibit A has been modified to be
 * consistent with Exhibit B.
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 * 
 * The Original Code is OpenEMM.
 * The Original Developer is the Initial Developer.
 * The Initial Developer of the Original Code is AGNITAS AG. All portions of
 * the code written by AGNITAS AG are Copyright (c) 2007 AGNITAS AG. All Rights
 * Reserved.
 * 
 * Contributor(s): AGNITAS AG. 
 ********************************************************************************/
# include	"xmlback.h"

static bool_t
expand_tags (tag_t *base) /*{{{*/
{
	bool_t		st;
	tag_t		*cur, *tmp;
	const xmlChar	*ptr;
	int		len;
	int		n, pos;
	int		bstart;
	xmlBufferPtr	out;
	
	st = true;
	for (cur = base; cur; cur = cur -> next) {
		for (tmp = base; tmp; tmp = tmp -> next)
			tmp -> used = (tmp == cur ? true : false);
		ptr = xmlBufferContent (cur -> value);
		len = xmlBufferLength (cur -> value);
		pos = 0;
		bstart = 0;
		out = NULL;
		while (pos < len) {
			n = xmlCharLength (ptr[pos]);
			if ((n == 1) && (ptr[pos] == '[')) {
				int	start, end;
				start = pos++;
				end = -1;
				while (pos < len) {
					n = xmlCharLength (ptr[pos]);
					if ((n == 1) && (ptr[pos] == ']')) {
						++pos;
						end = pos;
						break;
					}
					pos += n;
				}
				if (end != -1) {
					for (tmp = base; tmp; tmp = tmp -> next)
						if ((! tmp -> used) && tag_match (tmp, ptr + start, end - start))
							break;
					if (tmp) {
						if (! out)
							if (! (out = xmlBufferCreate ())) {
								st = false;
								break;
							}
						if (bstart < start)
							xmlBufferAdd (out, ptr + bstart, start - bstart);
						xmlBufferAdd (out, xmlBufferContent (tmp -> value), xmlBufferLength (tmp -> value));
						tmp -> used = true;
						bstart = pos;
					}
				}
			} else
				pos += n;
		}
		if (out) {
			if (bstart < len)
				xmlBufferAdd (out, ptr + bstart, len - bstart);
			xmlBufferFree (cur -> value);
			cur -> value = out;
		}
	}
	return st;
}/*}}}*/
bool_t
replace_tags (blockmail_t *blockmail, receiver_t *rec, block_t *block, bool_t ishtml) /*{{{*/
{
	bool_t		st;
	long		start, cur, next, end, len;
	const xmlChar	*content;
	int		tidx;
	tagpos_t	*tp;
	int		n;
	tag_t		*tag;
	
	st = expand_tags (rec -> tag);
	start = 0;
	end = xmlBufferLength (block -> content);
	content = xmlBufferContent (block -> content);
	xmlBufferEmpty (block -> in);
	for (cur = start, tidx = 0; cur < end; ) {
		if (tidx < block -> tagpos_count) {
			tp = block -> tagpos[tidx++];
			next = tp -> start;
		} else {
			tp = NULL;
			next = end;
		}
		len = next - cur;
		if (len > 0)
			xmlBufferAdd (block -> in, content + cur, len);
		if (tp) {
			cur = tp -> end;
			tag = NULL;
			if (tp -> type & (TP_DYNAMIC | TP_DYNAMICVALUE)) {
				if (tp -> tname) {
					dcache_t	*dc;
					const dyn_t	*dyn;
					
					for (dc = rec -> cache; dc; dc = dc -> next)
						if (! strcmp (dc -> name, tp -> tname))
							break;
					if (! dc)
						for (dyn = blockmail -> dyn; dyn; dyn = dyn -> next)
							if (! strcmp (dyn -> name, tp -> tname)) {
								if (dc = dcache_alloc (tp -> tname, dyn)) {
									dc -> next = rec -> cache;
									rec -> cache = dc;
								}
								break;
							}
					if (dc) {
						for (dyn = dc -> dyn; dyn; dyn = dyn -> sibling)
							if (dyn_match (dyn, blockmail -> eval))
								break;
						if (dyn) {
							block_t	*use;
						
							use = NULL;
							if (tp -> type & TP_DYNAMICVALUE) {
								for (n = 0; (! use) && (n < dyn -> block_count); ++n)
									switch (dyn -> block[n] -> nr) {
									case 0:
										if (! ishtml)
											use = dyn -> block[n];
										break;
									case 1:
										if (ishtml)
											use = dyn -> block[n];
										break;
									}
							} else if (tp -> type & TP_DYNAMIC)
								use = tp -> content;
							if (use)
								if (replace_tags (blockmail, rec, use, ishtml))
									xmlBufferAdd (block -> in, xmlBufferContent (use -> in), xmlBufferLength (use -> in));
								else
									st = false;
						}
					}
				}
			} else {
				for (n = 0; (n < 2) && (! tag); ++n) {
					for (tag = n ? blockmail -> gtag : rec -> tag; tag; tag = tag -> next)
						if (((tag -> hash == 0) || (tp -> hash == 0) || (tag -> hash == tp -> hash)) &&
						    (xmlEqual (tag -> name, tp -> name)))
							break;
				}
			}
			if (tag && ((n = xmlBufferLength (tag -> value)) > 0))
				xmlBufferAdd (block -> in, xmlBufferContent (tag -> value), n);
		} else
			cur = next;
	}
	return st;
}/*}}}*/
示例#2
0
文件: msgbind.c 项目: OPSF/uClinux
int main(int argc, char **argv)
{
 char source[FILENAME_MAX];             /* ReSource filename */
 char target_i[FILENAME_MAX];           /* .C-file containing pointers */
 char target_n[FILENAME_MAX];           /* All NMSGs */
 char target_f[FILENAME_MAX];           /* All FMSGs */
 char target_h[FILENAME_MAX];           /* Include file - all NMSGs/FMSGs */
 char target[FILENAME_MAX], locale[15];
 char c_system[32];
 char binding;
 char *msg_buffer;                      /* Messages may be large enough... */
 struct pool pool[32];                  /* Up to 32 separate msg arrays */
 int tpool, cur_pool=0, i;
 int buf_len;
 FILE *resfile, *ifile, *nfile, *ffile, *hfile;
 char pathsep[2];

 printf("MSGBIND v 1.65  [14/12/2002]  Not a part of any binary package!\n\n");
 if(argc<6)
 {
  printf("Usage: MSGBIND <resource> <target> <OS> <binding> <locale> [target directory],\n"
         "       e.g, to build MSG_SFXV.*, type MSGBIND MSG.RES MSG_SFXV DOS en\n"
         "\n"
         "The target directory is optional. If specified (e.g., BINARIES\\ENGLISH), all\n"
         "compiled .C files will be placed there.\n");
  exit(1);
 }
 msg_buffer=(char *)malloc_msg(MSG_SIZE);
 build_crc32_table();
 pathsep[0]=PATHSEP_DEFAULT;
 pathsep[1]='\0';
 strcpyn(source, argv[1], sizeof(source)-8);
 /* Fix for GCC/EMX: convert UNIX-like representations to DOS */
#if PATHSEP_UNIX!=PATHSEP_DEFAULT
 for(i=0; source[i]!='\0'; i++)
  if(source[i]==PATHSEP_UNIX)
   source[i]=PATHSEP_DEFAULT;
#endif
 if(strrchr(source, PATHSEP_DEFAULT)==NULL)
  rdir[0]='\0';
 else
 {
  strcpy(rdir, source);
  strrchr(rdir, PATHSEP_DEFAULT)[1]='\0';
 }
 strcpyn(target, argv[2], sizeof(target)-8);
 strcpyn(c_system, argv[3], sizeof(c_system));
 binding=tolower(argv[4][0]);
 /* Beginning with v 1.21, target directory may be also specified */
 if(argc==7)
 {
  strcpyn(target_i, argv[6], sizeof(target_i)-8);
  strcpyn(target_n, argv[6], sizeof(target_n)-8);
  strcpyn(target_f, argv[6], sizeof(target_f)-8);
  strcpyn(target_h, argv[6], sizeof(target_f)-8); /* v 1.41+ */
  if(argv[6][strlen(argv[6])-1]!=PATHSEP_DEFAULT);
  {
   strcat(target_i, pathsep);
   strcat(target_n, pathsep);
   strcat(target_f, pathsep);
   strcat(target_h, pathsep);
  }
 }
 else
 {
  target_i[0]='\0';
  target_n[0]='\0';
  target_f[0]='\0';
  target_h[0]='\0';
 }
 strcat(target_i, "i");
 strcat(target_n, "n");
 strcat(target_f, "f");
 strcat(target_i, argv[2]);
 strcat(target_n, argv[2]);
 strcat(target_f, argv[2]);
 strcat(target_h, argv[2]);
 /* The source has the extension .MSG, the targets are .H and .C */
 if(strchr(source, '.')==NULL)
  strcat(source, ".msg");
 strcat(target_i, ".c");
 strcat(target_n, ".c");
 strcat(target_f, ".c");
 strcat(target_h, ".h");
 strcpyn(locale, argv[5], sizeof(locale));
 strlwr(target);
 strlwr(c_system);
 strlwr(locale);
 /* Block out all signals, since this transaction is mission-critical */
 signal(SIGINT, SIG_IGN);
 #ifndef NO_TERM_HDL
  signal(SIGTERM, SIG_IGN);
 #endif
 if((resfile=fopen(source, m_r))==NULL)
 {
  printf("Can't open source file!\n");
  exit(2);
 }
 if((ifile=fopen(target_i, m_w))==NULL)
 {
  printf("Can't open index file!\n");
  exit(3);
 }
 if((nfile=fopen(target_n, m_w))==NULL)
 {
  printf("Can't open NMSG output file!\n");
  exit(3);
 }
 if((ffile=fopen(target_f, m_w))==NULL)
 {
  printf("Can't open FMSG output file!\n");
  exit(3);
 }
 if((hfile=fopen(target_h, m_w))==NULL)
 {
  printf("Can't open .h output file!\n");
  exit(3);
 }
 put_hdr(ifile, target_i, source);
 put_hdr(nfile, target_n, source);
 put_hdr(ffile, target_f, source);
 put_hdr(hfile, target_h, source);
 fputs(INCL, ifile);
 fputs(INCL, nfile);
 fputs(INCL, ffile);
 fprintf(ifile, "#include \"");
 for(i=0; target_h[i]!='\0'; i++)
  fputc(target_h[i]=='\\'?'/':target_h[i], ifile);
 fprintf(ifile, "\"\n\n");
 /* Ack. Now process the source file line by line... */
 while(get_msg(resfile, target, c_system, binding, locale, msg_buffer, MSG_SIZE)!=NULL)
 {
  expand_tags(msg_buffer, MSG_SIZE);
  fprintf(toupper(msgtype[0])=='N'?nfile:ffile, "char %s[]=%s;\n", msgname, msg_buffer);
  fprintf(hfile, "extern %s %s[];\n", toupper(msgtype[0])=='N'?M_NMSG:M_FMSG, msgname);
  /* Check if the message belongs to a pre-defined message pool */
  if(strcmp(msgpool, SKIP))
  {
   /* Pick a message heap */
   for(tpool=0; tpool<cur_pool; tpool++)
   {
    if(!strcmp(pool[tpool].name, msgpool))
     break;
   }
   /* Allocate new heap if needed */
   if(tpool==cur_pool)
   {
    if(cur_pool>=sizeof(pool))
    {
     printf("Too many message groups!\n");
     exit(4);
    }
    strcpy(pool[tpool].name, msgpool);
    pool[tpool].msgs=0;
    pool[tpool].crc32=CRC_MASK;
    pool[tpool].safesize=POOL_R_INC;
    pool[tpool].data=(char *)malloc_msg(POOL_R_INC);
    pool[tpool].st_class=toupper(msgtype[0])=='N'?'N':'F';
    sprintf(pool[tpool].data, "%cMSGP %s []={", pool[tpool].st_class, msgpool);
    pool[tpool].columns=pool[tpool].indent=strlen(pool[tpool].data);
    cur_pool++;
   }
   pool[tpool].msgs++;
   if(strlen(pool[tpool].data)+strlen(msgname)+pool[tpool].indent+16>pool[tpool].safesize)
   {
    if((pool[tpool].safesize+=POOL_R_INC)>POOL_SIZE)
    {
     printf("Message pool for %s exceeded %u bytes, exiting\n", msgpool, POOL_SIZE);
    }
    if((pool[tpool].data=realloc(pool[tpool].data, pool[tpool].safesize))==NULL)
    {
     printf("Unexpected lack of memory!r\n");
     exit(5);
    }
   }
   if((pool[tpool].columns+=strlen(msgname))>COLUMNS)
   {
    strcat(pool[tpool].data, "\n");
    pool[tpool].columns=pool[tpool].indent;
    pool[tpool].data[strlen(pool[tpool].data)+pool[tpool].indent]='\0';
    memset(pool[tpool].data+strlen(pool[tpool].data), 32, pool[tpool].indent);
   }
   strcat(pool[tpool].data, msgname);
   strcat(pool[tpool].data, ", ");
   strcpy(msg_buffer, msg_buffer+1);
   buf_len=strlen(msg_buffer);
   msg_buffer[--buf_len]='\0';
   patch_string(msg_buffer);
   crc32term=pool[tpool].crc32;
   crc32_for_string(msg_buffer);
   pool[tpool].crc32=crc32term;
  }
 }
 fputs("\n", hfile);
 /* First, flush the message pools... */
 for(tpool=0; tpool<cur_pool; tpool++)
 {
  strcat(pool[tpool].data, "NULL};\n\n");
  fputs(pool[tpool].data, ifile);
  free(pool[tpool].data);
  /* ...by the way, flushing the CRC-32 values */
  fprintf(hfile, "#define %s_CRC32 0x%08lx\n", pool[tpool].name, pool[tpool].crc32);
  fprintf(hfile, "extern %cMSGP %s[];\n", pool[tpool].st_class, pool[tpool].name);
 }
 /* Now, put an ending LF to all files */
 fputs("\n", ifile); fputs("\n", nfile); fputs("\n", ffile); fputs("\n", hfile);
 fclose(ifile); fclose(nfile); fclose(ffile); fclose(hfile);
 free(msg_buffer);
 return(0);                            /* Report no error */
}