goba            Mon Oct 21 11:53:27 2002 EDT

  Added files:                 
    /phpdoc/scripts     xml_proto.c 
  Log:
  Adding Brad's xml proto program so others can make use of it
  BTW it will probably be a good idea to port it to PHP ;P [sometime later!]
  
  
Index: phpdoc/scripts/xml_proto.c
+++ phpdoc/scripts/xml_proto.c
/* 
   +----------------------------------------------------------------------+
   | PHP Version 4                                                        |
   +----------------------------------------------------------------------+
   | Copyright (c) 1997-2002 The PHP Group                                |
   +----------------------------------------------------------------------+
   | This source file is subject to version 2.02 of the PHP licience,     |
   | that is bundled with this package in the file LICENCE and is         |
   | avalible through the world wide web at                               |
   | http://www.php.net/license/2_02.txt.                                 |
   | If uou did not receive a copy of the PHP license and are unable to   |
   | obtain it through the world wide web, please send a note to          |
   | [EMAIL PROTECTED] so we can mail you a copy immediately                |
   +----------------------------------------------------------------------+
   | Authors: Brad House <[EMAIL PROTECTED]>                               |
   +----------------------------------------------------------------------+
 */ 

/* $Id: xml_proto.c,v 1.1 2002/10/21 15:53:27 goba Exp $ */

/*
  This program generates XML files for functions implemented in a PHP
  extension with documented protos. Compile with this command line:
    
    gcc -Wall -O3 -o xml_proto xml_proto.c

  Then pass the php extension.c file to the new program, and it will
  write out a number of files based on the protos.
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

typedef struct XML_proto {
  char type[255];
  char variable[255];
} XML_proto;

typedef struct XML_functions {
  char function_type[255];
  char function_name[255];
  char function_name_fix[255];
  char purpose[1024];
  int num_args;
  XML_proto *args;
} XML_functions;

XML_functions *funclist=NULL;
int num_funcs=0;

int new_function()
{
  funclist=(XML_functions *)realloc(funclist, (num_funcs+1)*sizeof(XML_functions));
  funclist[num_funcs].function_name[0]=0;
  funclist[num_funcs].function_name_fix[0]=0;
  funclist[num_funcs].purpose[0]=0;
  funclist[num_funcs].num_args=0;
  funclist[num_funcs].args=NULL;
  num_funcs++;
  return(num_funcs-1);
}

char *fix_name(char *name)
{
  int len, i;
  char *ret=NULL;
  len=strlen(name);
  ret=(char *)malloc((len+1)*sizeof(char));
  memset(ret, 0, len+1);
  for (i=0; i<len; i++) {
    if (name[i] == '_') {
      ret[i]='-';
    } else {
      ret[i]=name[i];
    }
    ret[i+1]=0;
  }
  return(ret);
}

int function_add_name(int num, char *name)
{
  char *n;
  if (name != NULL) {
    strncpy(funclist[num].function_name, name, 255);
    n=fix_name(name);
    strncpy(funclist[num].function_name_fix, n, 255);
    free(n);
    return(1);
  }
  return(0);
}

int function_add_type(int num, char *type)
{
  if (type != NULL) {
    strncpy(funclist[num].function_type, type, 255);
    return(1);
  }
  return(0);
}

int function_add_purpose(int num, char *purpose)
{
  if (purpose != NULL) {
    strncpy(funclist[num].purpose, purpose, 1024);
    return(1);
  }
  return(0);
}

int function_add_arg(int num, char *type, char *argname)
{
  funclist[num].args=realloc(funclist[num].args, 
(funclist[num].num_args+1)*sizeof(XML_proto));
  funclist[num].args[funclist[num].num_args].type[0]=0;
  funclist[num].args[funclist[num].num_args].variable[0]=0;
  strncpy(funclist[num].args[funclist[num].num_args].type, type, 255);
  strncpy(funclist[num].args[funclist[num].num_args].variable, argname, 255);
  funclist[num].num_args++;
  return(1);
}

int write_xml_files()
{
  int i;
  int j;
  char filename[1024];
  FILE *fp;

  for (i=0; i<num_funcs; i++) {
    snprintf(filename, 1024, "%s.xml", funclist[i].function_name_fix);
    fp=fopen(filename, "wb");
    if (fp == NULL) {
      printf("Failed writing: %s\n", filename);
      continue;
    }
    fprintf(fp, "<?xml version='1.0' encoding='iso-8859-1'?>\n"
            "<!-- $Revision: 1.1 $ -->\n");
    fprintf(fp, "  <refentry id=\"function.%s\">\n",
            funclist[i].function_name_fix);
    fprintf(fp, "   <refnamediv>\n"
            "    <refname>%s</refname>\n"
            "    <refpurpose>%s</refpurpose>\n",
            funclist[i].function_name, funclist[i].purpose);
    fprintf(fp, "   </refnamediv>\n"
            "   <refsect1>\n"
            "    <title>Description</title>\n"
            "    <methodsynopsis>\n");
    fprintf(fp, "     <type>%s</type><methodname>%s</methodname>\n",
            funclist[i].function_type, funclist[i].function_name);
    
    for (j=0; j<funclist[i].num_args; j++) {
      fprintf(fp, "     
<methodparam><type>%s</type><parameter>%s</parameter></methodparam>\n",
              funclist[i].args[j].type, funclist[i].args[j].variable);
    }
    if (funclist[i].num_args == 0){
      fprintf(fp, "     <void/>\n");
    }
        
    fprintf(fp, "    </methodsynopsis>\n"
//          "     &warn.experimental.func;\n"
            "    <para>\n"
            "     &warn.undocumented.func;\n"
            "    </para>\n"
            "   </refsect1>\n"
            "  </refentry>\n"
            "\n"
            "<!-- Keep this comment at the end of the file\n"
            "Local variables:\n"
            "mode: sgml\n"
            "sgml-omittag:t\n"
            "sgml-shorttag:t\n"
            "sgml-minimize-attributes:nil\n"
            "sgml-always-quote-attributes:t\n"
            "sgml-indent-step:1\n"
            "sgml-indent-data:t\n"
            "indent-tabs-mode:nil\n"
            "sgml-parent-document:nil\n"
            "sgml-default-dtd-file:\"../../../../manual.ced\"\n"
            "sgml-exposed-tags:nil\n"
            "sgml-local-catalogs:nil\n"
            "sgml-local-ecat-files:nil\n"
            "End:\n"
            "vim600: syn=xml fen fdm=syntax fdl=2 si\n"
            "vim: et tw=78 syn=sgml\n"
            "vi: ts=1 sw=1\n"
            "-->\n");
    fclose(fp);
    printf("Wrote: %s\n", filename);
  }
  return(1);
}

long file_length(FILE *fp)
{
  long pos, len;
  pos=ftell(fp);
  fseek(fp, 0L, SEEK_END);
  len=ftell(fp);
  fseek(fp, pos, SEEK_SET);
  return(len);
}

char *read_file(char *filename)
{
  FILE *fp;
  char *buffer=NULL;
  long len;

  fp=fopen(filename, "rb");
  if (fp == NULL) return(NULL);
  len=file_length(fp);
  buffer=(char *)malloc((len+1)*sizeof(char));
  memset(buffer, 0, len+1);
  fread(buffer, len, sizeof(char), fp);
  fclose(fp);
  return(buffer);
}

char *midstr(char *string, long start, long len)
{
  char *ret=NULL;
  char *ptr=NULL;
  ret=(char *)malloc((len+1)*sizeof(char));
  ptr=string+start;
  memset(ret, 0, len+1);
  memcpy(ret, ptr, len);
  return(ret);
}

int parse_desc(int func_num, char *data)
{
  long len, i;
  int c;
  char temp[1024];
  int temp_len=0;
  int spaces=0;

  temp[0]=0;
  len=strlen(data);
  for (i=0; i<len; i++) {
    c=data[i];
    switch (c) {
      case '\r':
      case '\n':
      case ' ':
        if (!spaces) {
          spaces=1;
          temp[temp_len]=' ';
          temp_len++;
          temp[temp_len]=0;
        }
      break;

      default:
        spaces=0;
        temp[temp_len]=c;
        temp_len++;
        temp[temp_len]=0;
      break;
    }
  }
  function_add_purpose(func_num, temp);
  return(1);
}

int parse_proto(char *proto)
{
  long len, i;
  int c;
  int done=0;
  int start=0;
  int func_number=-1;
  int got_proto_def=0;
  int got_proto_type=0;
  int got_proto_name=0;
  int got_arg_type=0;
  int start_args=0;
  char temp[1024];
  char temp2[1024];
  int temp_len=0;

  len=strlen(proto);
  temp[0]=0;

  for (i=0; i<len; i++) {
    c=proto[i];
    switch (c) {
      case '\r':
      case '\n':
      case ' ':
        if (temp_len) {
          if (!got_proto_def) {
            if (strcasecmp(temp, "proto") != 0) {
              printf("Not a proper proto definition: %s\n", proto);
              return(0);
            } else {
              got_proto_def=1;
            }
          } else if (!got_proto_type) {
            func_number=new_function();
            function_add_type(func_number, temp);
            got_proto_type=1;
          } else if (!got_proto_name) {
            function_add_name(func_number, temp);
            got_proto_name=1;
          } else if (start_args && !got_arg_type) {
            got_arg_type=1;
            strcpy(temp2, temp);
          } else if (start_args && got_arg_type) {
            got_arg_type=0;
            function_add_arg(func_number, temp2, temp);
            temp2[0]=0;
          }
          temp_len=0;
          temp[0]=0;
        }
      break;

      case '(':
        if (got_proto_type && got_proto_def &&!got_proto_name) {
          function_add_name(func_number, temp);
          temp[0]=0;
          temp_len=0;
          start_args=1;
          got_proto_name=1;
        } else {
          printf("Not a proper proto definition -2: %s\n", proto);
          return(0);
        }

      break;

      case ')':
        if (start_args) {
          if (got_arg_type && temp_len) {
            function_add_arg(func_number, temp2, temp);
            temp[0]=0;
            temp_len=0;
          }
          done=1;
        } else {
          printf("Not a proper proto definition -4: %s\n", proto);
          return(0);
        }
      break;

      case ',':
        if (start_args && got_arg_type) {
          got_arg_type=0;
          function_add_arg(func_number, temp2, temp);
          temp2[0]=0;
          temp[0]=0;
          temp_len=0;
        } else {
          printf("Not a proper proto definition -3: %s\n", proto);
          return(0);
        }
      break;

      default:
        temp[temp_len]=c;
        temp_len++;
        temp[temp_len]=0;
      break;
    }
    if (done) {
      start=i+1;
      break;
    }
  }
  parse_desc(func_number, proto+start);
  return(1);
}



int parse_file(char *buffer)
{
  char *ptr=NULL, *temp1=NULL, *temp2=NULL;
  char *args=NULL;

  ptr=buffer;
  while (1) {
    temp1=strstr(ptr, "{{{");
    if (temp1 == NULL) break;
    temp2=strstr(temp1, "*/");
    if (temp2 == NULL) break;
    args=midstr(temp1, 3, strlen(temp1)-strlen(temp2)-3);
    parse_proto(args);
    free(args);
    ptr=temp2;
  }
  return(1);
}

int main(int argc, char **argv)
{
  char *contents=NULL;

  if (argc < 2) {
    printf("Usage: %s <extension file.c>\n", argv[0]);
    return(2);
  }
  contents=read_file(argv[1]);
  if (contents == NULL) {
    printf("Could not read %s\n", argv[1]);
  }
  parse_file(contents);
  free(contents);
  write_xml_files();
  return(1);
}
-- 
PHP Documentation Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to